1 // Distributed under the Boost Software License, Version 1.0. (See
2 // accompanying file LICENSE_1_0.txt or copy at
3 // http://www.boost.org/LICENSE_1_0.txt)
4 // (C) Copyright 2007 Anthony Williams
5 #ifndef THREAD_HEAP_ALLOC_HPP
6 #define THREAD_HEAP_ALLOC_HPP
7 #include <new>
8 #include <boost/thread/detail/config.hpp>
9 #include <boost/thread/win32/thread_primitives.hpp>
10 #include <stdexcept>
11 #include <boost/assert.hpp>
12 #include <boost/throw_exception.hpp>
13 #include <boost/core/no_exceptions_support.hpp>
14 
15 #include <boost/winapi/heap_memory.hpp>
16 
17 #include <boost/config/abi_prefix.hpp>
18 
19 namespace boost
20 {
21     namespace detail
22     {
allocate_raw_heap_memory(unsigned size)23         inline void* allocate_raw_heap_memory(unsigned size)
24         {
25             void* const heap_memory=winapi::HeapAlloc(winapi::GetProcessHeap(),0,size);
26             if(!heap_memory)
27             {
28                 boost::throw_exception(std::bad_alloc());
29             }
30             return heap_memory;
31         }
32 
free_raw_heap_memory(void * heap_memory)33         inline void free_raw_heap_memory(void* heap_memory)
34         {
35             BOOST_VERIFY(winapi::HeapFree(winapi::GetProcessHeap(),0,heap_memory)!=0);
36         }
37 #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && ! defined (BOOST_NO_CXX11_RVALUE_REFERENCES)
38         template<typename T,typename... Args>
heap_new(Args &&...args)39         inline T* heap_new(Args&&... args)
40         {
41           void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
42           BOOST_TRY
43           {
44               T* const data=new (heap_memory) T(static_cast<Args&&>(args)...);
45               return data;
46           }
47           BOOST_CATCH(...)
48           {
49               free_raw_heap_memory(heap_memory);
50               BOOST_RETHROW
51           }
52           BOOST_CATCH_END
53         }
54 #else
55         template<typename T>
heap_new()56         inline T* heap_new()
57         {
58             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
59             BOOST_TRY
60             {
61                 T* const data=new (heap_memory) T();
62                 return data;
63             }
64             BOOST_CATCH(...)
65             {
66                 free_raw_heap_memory(heap_memory);
67                 BOOST_RETHROW
68             }
69             BOOST_CATCH_END
70         }
71 
72 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
73         template<typename T,typename A1>
heap_new(A1 && a1)74         inline T* heap_new(A1&& a1)
75         {
76             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
77             BOOST_TRY
78             {
79                 T* const data=new (heap_memory) T(static_cast<A1&&>(a1));
80                 return data;
81             }
82             BOOST_CATCH(...)
83             {
84                 free_raw_heap_memory(heap_memory);
85                 BOOST_RETHROW
86             }
87             BOOST_CATCH_END
88         }
89         template<typename T,typename A1,typename A2>
heap_new(A1 && a1,A2 && a2)90         inline T* heap_new(A1&& a1,A2&& a2)
91         {
92             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
93             BOOST_TRY
94             {
95                 T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));
96                 return data;
97             }
98             BOOST_CATCH(...)
99             {
100                 free_raw_heap_memory(heap_memory);
101                 BOOST_RETHROW
102             }
103             BOOST_CATCH_END
104         }
105         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 && a1,A2 && a2,A3 && a3)106         inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)
107         {
108             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
109             BOOST_TRY
110             {
111                 T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
112                                                   static_cast<A3&&>(a3));
113                 return data;
114             }
115             BOOST_CATCH(...)
116             {
117                 free_raw_heap_memory(heap_memory);
118                 BOOST_RETHROW
119             }
120             BOOST_CATCH_END
121         }
122         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 && a1,A2 && a2,A3 && a3,A4 && a4)123         inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)
124         {
125             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
126             BOOST_TRY
127             {
128                 T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),
129                                                   static_cast<A3&&>(a3),static_cast<A4&&>(a4));
130                 return data;
131             }
132             BOOST_CATCH(...)
133             {
134                 free_raw_heap_memory(heap_memory);
135                 BOOST_RETHROW
136             }
137             BOOST_CATCH_END
138         }
139 #else
140         template<typename T,typename A1>
heap_new_impl(A1 a1)141         inline T* heap_new_impl(A1 a1)
142         {
143             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
144             BOOST_TRY
145             {
146                 T* const data=new (heap_memory) T(a1);
147                 return data;
148             }
149             BOOST_CATCH(...)
150             {
151                 free_raw_heap_memory(heap_memory);
152                 BOOST_RETHROW
153             }
154             BOOST_CATCH_END
155         }
156 
157         template<typename T,typename A1,typename A2>
heap_new_impl(A1 a1,A2 a2)158         inline T* heap_new_impl(A1 a1,A2 a2)
159         {
160             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
161             BOOST_TRY
162             {
163                 T* const data=new (heap_memory) T(a1,a2);
164                 return data;
165             }
166             BOOST_CATCH(...)
167             {
168                 free_raw_heap_memory(heap_memory);
169                 BOOST_RETHROW
170             }
171             BOOST_CATCH_END
172         }
173 
174         template<typename T,typename A1,typename A2,typename A3>
heap_new_impl(A1 a1,A2 a2,A3 a3)175         inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)
176         {
177             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
178             BOOST_TRY
179             {
180                 T* const data=new (heap_memory) T(a1,a2,a3);
181                 return data;
182             }
183             BOOST_CATCH(...)
184             {
185                 free_raw_heap_memory(heap_memory);
186                 BOOST_RETHROW
187             }
188             BOOST_CATCH_END
189         }
190 
191         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)192         inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)
193         {
194             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
195             BOOST_TRY
196             {
197                 T* const data=new (heap_memory) T(a1,a2,a3,a4);
198                 return data;
199             }
200             BOOST_CATCH(...)
201             {
202                 free_raw_heap_memory(heap_memory);
203                 BOOST_RETHROW
204             }
205             BOOST_CATCH_END
206         }
207         template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5>
heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)208         inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)
209         {
210             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
211             BOOST_TRY
212             {
213                 T* const data=new (heap_memory) T(a1,a2,a3,a4,a5);
214                 return data;
215             }
216             BOOST_CATCH(...)
217             {
218                 free_raw_heap_memory(heap_memory);
219                 BOOST_RETHROW
220             }
221             BOOST_CATCH_END
222         }
223         template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6>
heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6)224         inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6)
225         {
226             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
227             BOOST_TRY
228             {
229                 T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6);
230                 return data;
231             }
232             BOOST_CATCH(...)
233             {
234                 free_raw_heap_memory(heap_memory);
235                 BOOST_RETHROW
236             }
237             BOOST_CATCH_END
238         }
239         template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7>
heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7)240         inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7)
241         {
242             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
243             BOOST_TRY
244             {
245                 T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6,a7);
246                 return data;
247             }
248             BOOST_CATCH(...)
249             {
250                 free_raw_heap_memory(heap_memory);
251                 BOOST_RETHROW
252             }
253             BOOST_CATCH_END
254         }
255         template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8>
heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8)256         inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8)
257         {
258             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
259             BOOST_TRY
260             {
261                 T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6,a7,a8);
262                 return data;
263             }
264             BOOST_CATCH(...)
265             {
266                 free_raw_heap_memory(heap_memory);
267                 BOOST_RETHROW
268             }
269             BOOST_CATCH_END
270         }
271         template<typename T,typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8,typename A9>
heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9)272         inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9)
273         {
274             void* const heap_memory=allocate_raw_heap_memory(sizeof(T));
275             BOOST_TRY
276             {
277                 T* const data=new (heap_memory) T(a1,a2,a3,a4,a5,a6,a7,a8,a9);
278                 return data;
279             }
280             BOOST_CATCH(...)
281             {
282                 free_raw_heap_memory(heap_memory);
283                 BOOST_RETHROW
284             }
285             BOOST_CATCH_END
286         }
287 
288 
289         template<typename T,typename A1>
heap_new(A1 const & a1)290         inline T* heap_new(A1 const& a1)
291         {
292             return heap_new_impl<T,A1 const&>(a1);
293         }
294         template<typename T,typename A1>
heap_new(A1 & a1)295         inline T* heap_new(A1& a1)
296         {
297             return heap_new_impl<T,A1&>(a1);
298         }
299 
300         template<typename T,typename A1,typename A2>
heap_new(A1 const & a1,A2 const & a2)301         inline T* heap_new(A1 const& a1,A2 const& a2)
302         {
303             return heap_new_impl<T,A1 const&,A2 const&>(a1,a2);
304         }
305         template<typename T,typename A1,typename A2>
heap_new(A1 & a1,A2 const & a2)306         inline T* heap_new(A1& a1,A2 const& a2)
307         {
308             return heap_new_impl<T,A1&,A2 const&>(a1,a2);
309         }
310         template<typename T,typename A1,typename A2>
heap_new(A1 const & a1,A2 & a2)311         inline T* heap_new(A1 const& a1,A2& a2)
312         {
313             return heap_new_impl<T,A1 const&,A2&>(a1,a2);
314         }
315         template<typename T,typename A1,typename A2>
heap_new(A1 & a1,A2 & a2)316         inline T* heap_new(A1& a1,A2& a2)
317         {
318             return heap_new_impl<T,A1&,A2&>(a1,a2);
319         }
320 
321         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 const & a1,A2 const & a2,A3 const & a3)322         inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3)
323         {
324             return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3);
325         }
326         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 & a1,A2 const & a2,A3 const & a3)327         inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3)
328         {
329             return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3);
330         }
331         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 const & a1,A2 & a2,A3 const & a3)332         inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3)
333         {
334             return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3);
335         }
336         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 & a1,A2 & a2,A3 const & a3)337         inline T* heap_new(A1& a1,A2& a2,A3 const& a3)
338         {
339             return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3);
340         }
341 
342         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 const & a1,A2 const & a2,A3 & a3)343         inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3)
344         {
345             return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3);
346         }
347         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 & a1,A2 const & a2,A3 & a3)348         inline T* heap_new(A1& a1,A2 const& a2,A3& a3)
349         {
350             return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3);
351         }
352         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 const & a1,A2 & a2,A3 & a3)353         inline T* heap_new(A1 const& a1,A2& a2,A3& a3)
354         {
355             return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3);
356         }
357         template<typename T,typename A1,typename A2,typename A3>
heap_new(A1 & a1,A2 & a2,A3 & a3)358         inline T* heap_new(A1& a1,A2& a2,A3& a3)
359         {
360             return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3);
361         }
362 
363         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & a4)364         inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4)
365         {
366             return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
367         }
368         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 const & a2,A3 const & a3,A4 const & a4)369         inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4)
370         {
371             return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4);
372         }
373         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 & a2,A3 const & a3,A4 const & a4)374         inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4)
375         {
376             return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
377         }
378         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 & a2,A3 const & a3,A4 const & a4)379         inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4)
380         {
381             return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4);
382         }
383 
384         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 const & a2,A3 & a3,A4 const & a4)385         inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4)
386         {
387             return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
388         }
389         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 const & a2,A3 & a3,A4 const & a4)390         inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4)
391         {
392             return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4);
393         }
394         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 & a2,A3 & a3,A4 const & a4)395         inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4)
396         {
397             return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
398         }
399         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 & a2,A3 & a3,A4 const & a4)400         inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4)
401         {
402             return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4);
403         }
404         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 const & a2,A3 const & a3,A4 & a4)405         inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4)
406         {
407             return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
408         }
409         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 const & a2,A3 const & a3,A4 & a4)410         inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4)
411         {
412             return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4);
413         }
414         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 & a2,A3 const & a3,A4 & a4)415         inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4)
416         {
417             return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
418         }
419         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 & a2,A3 const & a3,A4 & a4)420         inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4)
421         {
422             return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4);
423         }
424 
425         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 const & a2,A3 & a3,A4 & a4)426         inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4)
427         {
428             return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
429         }
430         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 const & a2,A3 & a3,A4 & a4)431         inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4)
432         {
433             return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4);
434         }
435         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 const & a1,A2 & a2,A3 & a3,A4 & a4)436         inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4)
437         {
438             return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4);
439         }
440         template<typename T,typename A1,typename A2,typename A3,typename A4>
heap_new(A1 & a1,A2 & a2,A3 & a3,A4 & a4)441         inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4)
442         {
443             return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);
444         }
445 
446 #endif
447 #endif
448         template<typename T>
heap_delete(T * data)449         inline void heap_delete(T* data)
450         {
451             data->~T();
452             free_raw_heap_memory(data);
453         }
454 
455         template<typename T>
456         struct do_heap_delete
457         {
operator ()boost::detail::do_heap_delete458             void operator()(T* data) const
459             {
460                 detail::heap_delete(data);
461             }
462         };
463     }
464 }
465 
466 #include <boost/config/abi_suffix.hpp>
467 
468 
469 #endif
470