allocate_shared_array.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Copyright (c) 2012 Glen Joseph Fernandes
  3. * glenfe at live dot com
  4. *
  5. * Distributed under the Boost Software License,
  6. * Version 1.0. (See accompanying file LICENSE_1_0.txt
  7. * or copy at http://boost.org/LICENSE_1_0.txt)
  8. */
  9. #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
  10. #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
  11. #include <boost/smart_ptr/shared_ptr.hpp>
  12. #include <boost/smart_ptr/detail/allocate_array_helper.hpp>
  13. #include <boost/smart_ptr/detail/array_deleter.hpp>
  14. #include <boost/smart_ptr/detail/array_traits.hpp>
  15. #include <boost/smart_ptr/detail/sp_if_array.hpp>
  16. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  17. #include <initializer_list>
  18. #endif
  19. namespace boost {
  20. template<typename T, typename A>
  21. inline typename boost::detail::sp_if_array<T>::type
  22. allocate_shared(const A& allocator, std::size_t size) {
  23. typedef typename boost::detail::array_inner<T>::type T1;
  24. typedef typename boost::detail::array_base<T1>::type T2;
  25. T1* p1 = 0;
  26. T2* p2 = 0;
  27. std::size_t n1 = size * boost::detail::array_total<T1>::size;
  28. boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
  29. boost::detail::array_deleter<T2[]> d1(n1);
  30. boost::shared_ptr<T> s1(p1, d1, a1);
  31. typedef boost::detail::array_deleter<T2[]>* D2;
  32. p1 = reinterpret_cast<T1*>(p2);
  33. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  34. d2->init(p2);
  35. return boost::shared_ptr<T>(s1, p1);
  36. }
  37. #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  38. template<typename T, typename A, typename... Args>
  39. inline typename boost::detail::sp_if_array<T>::type
  40. allocate_shared(const A& allocator, std::size_t size, Args&&... args) {
  41. typedef typename boost::detail::array_inner<T>::type T1;
  42. typedef typename boost::detail::array_base<T1>::type T2;
  43. T1* p1 = 0;
  44. T2* p2 = 0;
  45. std::size_t n1 = size * boost::detail::array_total<T1>::size;
  46. boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
  47. boost::detail::array_deleter<T2[]> d1(n1);
  48. boost::shared_ptr<T> s1(p1, d1, a1);
  49. typedef boost::detail::array_deleter<T2[]>* D2;
  50. p1 = reinterpret_cast<T1*>(p2);
  51. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  52. d2->init(p2, boost::detail::sp_forward<Args>(args)...);
  53. return boost::shared_ptr<T>(s1, p1);
  54. }
  55. template<typename T, typename A, typename... Args>
  56. inline typename boost::detail::sp_if_size_array<T>::type
  57. allocate_shared(const A& allocator, Args&&... args) {
  58. typedef typename boost::detail::array_inner<T>::type T1;
  59. typedef typename boost::detail::array_base<T1>::type T2;
  60. enum {
  61. N = boost::detail::array_total<T>::size
  62. };
  63. T1* p1 = 0;
  64. T2* p2 = 0;
  65. boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
  66. boost::detail::array_deleter<T2[N]> d1;
  67. boost::shared_ptr<T> s1(p1, d1, a1);
  68. typedef boost::detail::array_deleter<T2[N]>* D2;
  69. p1 = reinterpret_cast<T1*>(p2);
  70. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  71. d2->init(p2, boost::detail::sp_forward<Args>(args)...);
  72. return boost::shared_ptr<T>(s1, p1);
  73. }
  74. #endif
  75. #if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
  76. template<typename T, typename A>
  77. inline typename boost::detail::sp_if_size_array<T>::type
  78. allocate_shared(const A& allocator, const T& list) {
  79. typedef typename boost::detail::array_inner<T>::type T1;
  80. typedef typename boost::detail::array_base<T1>::type T2;
  81. typedef const T2 T3;
  82. enum {
  83. N = boost::detail::array_total<T>::size
  84. };
  85. T1* p1 = 0;
  86. T2* p2 = 0;
  87. T3* p3 = 0;
  88. boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
  89. boost::detail::array_deleter<T2[N]> d1;
  90. boost::shared_ptr<T> s1(p1, d1, a1);
  91. typedef boost::detail::array_deleter<T2[N]>* D2;
  92. p3 = reinterpret_cast<T3*>(list);
  93. p1 = reinterpret_cast<T1*>(p2);
  94. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  95. d2->init_list(p2, p3);
  96. return boost::shared_ptr<T>(s1, p1);
  97. }
  98. template<typename T, typename A>
  99. inline typename boost::detail::sp_if_array<T>::type
  100. allocate_shared(const A& allocator, std::size_t size,
  101. const typename boost::detail::array_inner<T>::type& list) {
  102. typedef typename boost::detail::array_inner<T>::type T1;
  103. typedef typename boost::detail::array_base<T1>::type T2;
  104. typedef const T2 T3;
  105. enum {
  106. M = boost::detail::array_total<T1>::size
  107. };
  108. T1* p1 = 0;
  109. T2* p2 = 0;
  110. T3* p3 = 0;
  111. std::size_t n1 = M * size;
  112. boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
  113. boost::detail::array_deleter<T2[]> d1(n1);
  114. boost::shared_ptr<T> s1(p1, d1, a1);
  115. typedef boost::detail::array_deleter<T2[]>* D2;
  116. p3 = reinterpret_cast<T3*>(list);
  117. p1 = reinterpret_cast<T1*>(p2);
  118. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  119. d2->template init_list<M>(p2, p3);
  120. return boost::shared_ptr<T>(s1, p1);
  121. }
  122. template<typename T, typename A>
  123. inline typename boost::detail::sp_if_size_array<T>::type
  124. allocate_shared(const A& allocator,
  125. const typename boost::detail::array_inner<T>::type& list) {
  126. typedef typename boost::detail::array_inner<T>::type T1;
  127. typedef typename boost::detail::array_base<T1>::type T2;
  128. typedef const T2 T3;
  129. enum {
  130. M = boost::detail::array_total<T1>::size,
  131. N = boost::detail::array_total<T>::size
  132. };
  133. T1* p1 = 0;
  134. T2* p2 = 0;
  135. T3* p3 = 0;
  136. boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
  137. boost::detail::array_deleter<T2[N]> d1;
  138. boost::shared_ptr<T> s1(p1, d1, a1);
  139. typedef boost::detail::array_deleter<T2[N]>* D2;
  140. p3 = reinterpret_cast<T3*>(list);
  141. p1 = reinterpret_cast<T1*>(p2);
  142. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  143. d2->template init_list<M>(p2, p3);
  144. return boost::shared_ptr<T>(s1, p1);
  145. }
  146. #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
  147. template<typename T, typename A>
  148. inline typename boost::detail::sp_if_array<T>::type
  149. allocate_shared(const A& allocator,
  150. std::initializer_list<typename boost::detail::array_inner<T>::type> list) {
  151. typedef typename boost::detail::array_inner<T>::type T1;
  152. typedef typename boost::detail::array_base<T1>::type T2;
  153. typedef const T2 T3;
  154. T1* p1 = 0;
  155. T2* p2 = 0;
  156. T3* p3 = 0;
  157. std::size_t n1 = list.size() * boost::detail::array_total<T1>::size;
  158. boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
  159. boost::detail::array_deleter<T2[]> d1(n1);
  160. boost::shared_ptr<T> s1(p1, d1, a1);
  161. typedef boost::detail::array_deleter<T2[]>* D2;
  162. p3 = reinterpret_cast<T3*>(list.begin());
  163. p1 = reinterpret_cast<T1*>(p2);
  164. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  165. d2->init_list(p2, p3);
  166. return boost::shared_ptr<T>(s1, p1);
  167. }
  168. #endif
  169. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  170. template<typename T, typename A>
  171. inline typename boost::detail::sp_if_array<T>::type
  172. allocate_shared(const A& allocator, std::size_t size,
  173. typename boost::detail::array_base<T>::type&& value) {
  174. typedef typename boost::detail::array_inner<T>::type T1;
  175. typedef typename boost::detail::array_base<T1>::type T2;
  176. T1* p1 = 0;
  177. T2* p2 = 0;
  178. std::size_t n1 = size * boost::detail::array_total<T1>::size;
  179. boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
  180. boost::detail::array_deleter<T2[]> d1(n1);
  181. boost::shared_ptr<T> s1(p1, d1, a1);
  182. typedef boost::detail::array_deleter<T2[]>* D2;
  183. p1 = reinterpret_cast<T1*>(p2);
  184. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  185. d2->init(p2, boost::detail::sp_forward<T2>(value));
  186. return boost::shared_ptr<T>(s1, p1);
  187. }
  188. template<typename T, typename A>
  189. inline typename boost::detail::sp_if_size_array<T>::type
  190. allocate_shared(const A& allocator,
  191. typename boost::detail::array_base<T>::type&& value) {
  192. typedef typename boost::detail::array_inner<T>::type T1;
  193. typedef typename boost::detail::array_base<T1>::type T2;
  194. enum {
  195. N = boost::detail::array_total<T>::size
  196. };
  197. T1* p1 = 0;
  198. T2* p2 = 0;
  199. boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
  200. boost::detail::array_deleter<T2[N]> d1;
  201. boost::shared_ptr<T> s1(p1, d1, a1);
  202. typedef boost::detail::array_deleter<T2[N]>* D2;
  203. p1 = reinterpret_cast<T1*>(p2);
  204. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  205. d2->init(p2, boost::detail::sp_forward<T2>(value));
  206. return boost::shared_ptr<T>(s1, p1);
  207. }
  208. #endif
  209. #endif
  210. template<typename T, typename A>
  211. inline typename boost::detail::sp_if_array<T>::type
  212. allocate_shared_noinit(const A& allocator, std::size_t size) {
  213. typedef typename boost::detail::array_inner<T>::type T1;
  214. typedef typename boost::detail::array_base<T1>::type T2;
  215. T1* p1 = 0;
  216. T2* p2 = 0;
  217. std::size_t n1 = size * boost::detail::array_total<T1>::size;
  218. boost::detail::allocate_array_helper<A, T2[]> a1(allocator, n1, &p2);
  219. boost::detail::array_deleter<T2[]> d1(n1);
  220. boost::shared_ptr<T> s1(p1, d1, a1);
  221. typedef boost::detail::array_deleter<T2[]>* D2;
  222. p1 = reinterpret_cast<T1*>(p2);
  223. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  224. d2->noinit(p2);
  225. return boost::shared_ptr<T>(s1, p1);
  226. }
  227. template<typename T, typename A>
  228. inline typename boost::detail::sp_if_size_array<T>::type
  229. allocate_shared_noinit(const A& allocator) {
  230. typedef typename boost::detail::array_inner<T>::type T1;
  231. typedef typename boost::detail::array_base<T1>::type T2;
  232. enum {
  233. N = boost::detail::array_total<T>::size
  234. };
  235. T1* p1 = 0;
  236. T2* p2 = 0;
  237. boost::detail::allocate_array_helper<A, T2[N]> a1(allocator, &p2);
  238. boost::detail::array_deleter<T2[N]> d1;
  239. boost::shared_ptr<T> s1(p1, d1, a1);
  240. typedef boost::detail::array_deleter<T2[N]>* D2;
  241. p1 = reinterpret_cast<T1*>(p2);
  242. D2 d2 = static_cast<D2>(s1._internal_get_untyped_deleter());
  243. d2->noinit(p2);
  244. return boost::shared_ptr<T>(s1, p1);
  245. }
  246. }
  247. #endif