thread_heap_alloc.hpp 16 KB

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