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