make_shared_object.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
  2. #define BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED
  3. // make_shared_object.hpp
  4. //
  5. // Copyright (c) 2007, 2008, 2012 Peter Dimov
  6. //
  7. // Distributed under the Boost Software License, Version 1.0.
  8. // See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt
  10. //
  11. // See http://www.boost.org/libs/smart_ptr/ for documentation.
  12. #include <boost/config.hpp>
  13. #include <boost/move/core.hpp>
  14. #include <boost/move/utility_core.hpp>
  15. #include <boost/smart_ptr/shared_ptr.hpp>
  16. #include <boost/smart_ptr/detail/sp_forward.hpp>
  17. #include <boost/smart_ptr/detail/sp_noexcept.hpp>
  18. #include <boost/type_traits/type_with_alignment.hpp>
  19. #include <boost/type_traits/alignment_of.hpp>
  20. #include <cstddef>
  21. #include <new>
  22. namespace boost
  23. {
  24. namespace detail
  25. {
  26. template< std::size_t N, std::size_t A > struct sp_aligned_storage
  27. {
  28. union type
  29. {
  30. char data_[ N ];
  31. typename boost::type_with_alignment< A >::type align_;
  32. };
  33. };
  34. template< class T > class sp_ms_deleter
  35. {
  36. private:
  37. typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
  38. bool initialized_;
  39. storage_type storage_;
  40. private:
  41. void destroy() BOOST_SP_NOEXCEPT
  42. {
  43. if( initialized_ )
  44. {
  45. #if defined( __GNUC__ )
  46. // fixes incorrect aliasing warning
  47. T * p = reinterpret_cast< T* >( storage_.data_ );
  48. p->~T();
  49. #else
  50. reinterpret_cast< T* >( storage_.data_ )->~T();
  51. #endif
  52. initialized_ = false;
  53. }
  54. }
  55. public:
  56. sp_ms_deleter() BOOST_SP_NOEXCEPT : initialized_( false )
  57. {
  58. }
  59. template<class A> explicit sp_ms_deleter( A const & ) BOOST_SP_NOEXCEPT : initialized_( false )
  60. {
  61. }
  62. // optimization: do not copy storage_
  63. sp_ms_deleter( sp_ms_deleter const & ) BOOST_SP_NOEXCEPT : initialized_( false )
  64. {
  65. }
  66. ~sp_ms_deleter() BOOST_SP_NOEXCEPT
  67. {
  68. destroy();
  69. }
  70. void operator()( T * ) BOOST_SP_NOEXCEPT
  71. {
  72. destroy();
  73. }
  74. static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
  75. {
  76. }
  77. void * address() BOOST_SP_NOEXCEPT
  78. {
  79. return storage_.data_;
  80. }
  81. void set_initialized() BOOST_SP_NOEXCEPT
  82. {
  83. initialized_ = true;
  84. }
  85. };
  86. template< class T, class A > class sp_as_deleter
  87. {
  88. private:
  89. typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
  90. storage_type storage_;
  91. A a_;
  92. bool initialized_;
  93. private:
  94. void destroy() BOOST_SP_NOEXCEPT
  95. {
  96. if( initialized_ )
  97. {
  98. T * p = reinterpret_cast< T* >( storage_.data_ );
  99. #if !defined( BOOST_NO_CXX11_ALLOCATOR )
  100. std::allocator_traits<A>::destroy( a_, p );
  101. #else
  102. p->~T();
  103. #endif
  104. initialized_ = false;
  105. }
  106. }
  107. public:
  108. sp_as_deleter( A const & a ) BOOST_SP_NOEXCEPT : a_( a ), initialized_( false )
  109. {
  110. }
  111. // optimization: do not copy storage_
  112. sp_as_deleter( sp_as_deleter const & r ) BOOST_SP_NOEXCEPT : a_( r.a_), initialized_( false )
  113. {
  114. }
  115. ~sp_as_deleter() BOOST_SP_NOEXCEPT
  116. {
  117. destroy();
  118. }
  119. void operator()( T * ) BOOST_SP_NOEXCEPT
  120. {
  121. destroy();
  122. }
  123. static void operator_fn( T* ) BOOST_SP_NOEXCEPT // operator() can't be static
  124. {
  125. }
  126. void * address() BOOST_SP_NOEXCEPT
  127. {
  128. return storage_.data_;
  129. }
  130. void set_initialized() BOOST_SP_NOEXCEPT
  131. {
  132. initialized_ = true;
  133. }
  134. };
  135. template< class T > struct sp_if_not_array
  136. {
  137. typedef boost::shared_ptr< T > type;
  138. };
  139. #if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
  140. template< class T > struct sp_if_not_array< T[] >
  141. {
  142. };
  143. #if !defined( BOOST_BORLANDC ) || !BOOST_WORKAROUND( BOOST_BORLANDC, < 0x600 )
  144. template< class T, std::size_t N > struct sp_if_not_array< T[N] >
  145. {
  146. };
  147. #endif
  148. #endif
  149. } // namespace detail
  150. #if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
  151. # define BOOST_SP_MSD( T ) boost::detail::sp_inplace_tag< boost::detail::sp_ms_deleter< T > >()
  152. #else
  153. # define BOOST_SP_MSD( T ) boost::detail::sp_ms_deleter< T >()
  154. #endif
  155. // _noinit versions
  156. template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared_noinit()
  157. {
  158. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  159. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  160. void * pv = pd->address();
  161. ::new( pv ) T;
  162. pd->set_initialized();
  163. T * pt2 = static_cast< T* >( pv );
  164. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  165. return boost::shared_ptr< T >( pt, pt2 );
  166. }
  167. template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared_noinit( A const & a )
  168. {
  169. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  170. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  171. void * pv = pd->address();
  172. ::new( pv ) T;
  173. pd->set_initialized();
  174. T * pt2 = static_cast< T* >( pv );
  175. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  176. return boost::shared_ptr< T >( pt, pt2 );
  177. }
  178. #if !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  179. // Variadic templates, rvalue reference
  180. template< class T, class... Args > typename boost::detail::sp_if_not_array< T >::type make_shared( Args && ... args )
  181. {
  182. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  183. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  184. void * pv = pd->address();
  185. ::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
  186. pd->set_initialized();
  187. T * pt2 = static_cast< T* >( pv );
  188. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  189. return boost::shared_ptr< T >( pt, pt2 );
  190. }
  191. template< class T, class A, class... Args > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, Args && ... args )
  192. {
  193. #if !defined( BOOST_NO_CXX11_ALLOCATOR )
  194. typedef typename std::allocator_traits<A>::template rebind_alloc<T> A2;
  195. A2 a2( a );
  196. typedef boost::detail::sp_as_deleter< T, A2 > D;
  197. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a2 );
  198. #else
  199. typedef boost::detail::sp_ms_deleter< T > D;
  200. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_inplace_tag<D>(), a );
  201. #endif
  202. D * pd = static_cast< D* >( pt._internal_get_untyped_deleter() );
  203. void * pv = pd->address();
  204. #if !defined( BOOST_NO_CXX11_ALLOCATOR )
  205. std::allocator_traits<A2>::construct( a2, static_cast< T* >( pv ), boost::detail::sp_forward<Args>( args )... );
  206. #else
  207. ::new( pv ) T( boost::detail::sp_forward<Args>( args )... );
  208. #endif
  209. pd->set_initialized();
  210. T * pt2 = static_cast< T* >( pv );
  211. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  212. return boost::shared_ptr< T >( pt, pt2 );
  213. }
  214. #else // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  215. // Common zero-argument versions
  216. template< class T > typename boost::detail::sp_if_not_array< T >::type make_shared()
  217. {
  218. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  219. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  220. void * pv = pd->address();
  221. ::new( pv ) T();
  222. pd->set_initialized();
  223. T * pt2 = static_cast< T* >( pv );
  224. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  225. return boost::shared_ptr< T >( pt, pt2 );
  226. }
  227. template< class T, class A > typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a )
  228. {
  229. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  230. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  231. void * pv = pd->address();
  232. ::new( pv ) T();
  233. pd->set_initialized();
  234. T * pt2 = static_cast< T* >( pv );
  235. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  236. return boost::shared_ptr< T >( pt, pt2 );
  237. }
  238. // C++03 version
  239. template< class T, class A1 >
  240. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1 )
  241. {
  242. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  243. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  244. void * pv = pd->address();
  245. ::new( pv ) T(
  246. boost::forward<A1>( a1 )
  247. );
  248. pd->set_initialized();
  249. T * pt2 = static_cast< T* >( pv );
  250. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  251. return boost::shared_ptr< T >( pt, pt2 );
  252. }
  253. template< class T, class A, class A1 >
  254. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1 )
  255. {
  256. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  257. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  258. void * pv = pd->address();
  259. ::new( pv ) T(
  260. boost::forward<A1>( a1 )
  261. );
  262. pd->set_initialized();
  263. T * pt2 = static_cast< T* >( pv );
  264. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  265. return boost::shared_ptr< T >( pt, pt2 );
  266. }
  267. template< class T, class A1, class A2 >
  268. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
  269. {
  270. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  271. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  272. void * pv = pd->address();
  273. ::new( pv ) T(
  274. boost::forward<A1>( a1 ),
  275. boost::forward<A2>( a2 )
  276. );
  277. pd->set_initialized();
  278. T * pt2 = static_cast< T* >( pv );
  279. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  280. return boost::shared_ptr< T >( pt, pt2 );
  281. }
  282. template< class T, class A, class A1, class A2 >
  283. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2 )
  284. {
  285. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  286. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  287. void * pv = pd->address();
  288. ::new( pv ) T(
  289. boost::forward<A1>( a1 ),
  290. boost::forward<A2>( a2 )
  291. );
  292. pd->set_initialized();
  293. T * pt2 = static_cast< T* >( pv );
  294. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  295. return boost::shared_ptr< T >( pt, pt2 );
  296. }
  297. template< class T, class A1, class A2, class A3 >
  298. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
  299. {
  300. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  301. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  302. void * pv = pd->address();
  303. ::new( pv ) T(
  304. boost::forward<A1>( a1 ),
  305. boost::forward<A2>( a2 ),
  306. boost::forward<A3>( a3 )
  307. );
  308. pd->set_initialized();
  309. T * pt2 = static_cast< T* >( pv );
  310. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  311. return boost::shared_ptr< T >( pt, pt2 );
  312. }
  313. template< class T, class A, class A1, class A2, class A3 >
  314. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3 )
  315. {
  316. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  317. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  318. void * pv = pd->address();
  319. ::new( pv ) T(
  320. boost::forward<A1>( a1 ),
  321. boost::forward<A2>( a2 ),
  322. boost::forward<A3>( a3 )
  323. );
  324. pd->set_initialized();
  325. T * pt2 = static_cast< T* >( pv );
  326. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  327. return boost::shared_ptr< T >( pt, pt2 );
  328. }
  329. template< class T, class A1, class A2, class A3, class A4 >
  330. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
  331. {
  332. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  333. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  334. void * pv = pd->address();
  335. ::new( pv ) T(
  336. boost::forward<A1>( a1 ),
  337. boost::forward<A2>( a2 ),
  338. boost::forward<A3>( a3 ),
  339. boost::forward<A4>( a4 )
  340. );
  341. pd->set_initialized();
  342. T * pt2 = static_cast< T* >( pv );
  343. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  344. return boost::shared_ptr< T >( pt, pt2 );
  345. }
  346. template< class T, class A, class A1, class A2, class A3, class A4 >
  347. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4 )
  348. {
  349. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  350. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  351. void * pv = pd->address();
  352. ::new( pv ) T(
  353. boost::forward<A1>( a1 ),
  354. boost::forward<A2>( a2 ),
  355. boost::forward<A3>( a3 ),
  356. boost::forward<A4>( a4 )
  357. );
  358. pd->set_initialized();
  359. T * pt2 = static_cast< T* >( pv );
  360. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  361. return boost::shared_ptr< T >( pt, pt2 );
  362. }
  363. template< class T, class A1, class A2, class A3, class A4, class A5 >
  364. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
  365. {
  366. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  367. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  368. void * pv = pd->address();
  369. ::new( pv ) T(
  370. boost::forward<A1>( a1 ),
  371. boost::forward<A2>( a2 ),
  372. boost::forward<A3>( a3 ),
  373. boost::forward<A4>( a4 ),
  374. boost::forward<A5>( a5 )
  375. );
  376. pd->set_initialized();
  377. T * pt2 = static_cast< T* >( pv );
  378. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  379. return boost::shared_ptr< T >( pt, pt2 );
  380. }
  381. template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
  382. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5 )
  383. {
  384. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  385. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  386. void * pv = pd->address();
  387. ::new( pv ) T(
  388. boost::forward<A1>( a1 ),
  389. boost::forward<A2>( a2 ),
  390. boost::forward<A3>( a3 ),
  391. boost::forward<A4>( a4 ),
  392. boost::forward<A5>( a5 )
  393. );
  394. pd->set_initialized();
  395. T * pt2 = static_cast< T* >( pv );
  396. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  397. return boost::shared_ptr< T >( pt, pt2 );
  398. }
  399. template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
  400. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
  401. {
  402. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  403. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  404. void * pv = pd->address();
  405. ::new( pv ) T(
  406. boost::forward<A1>( a1 ),
  407. boost::forward<A2>( a2 ),
  408. boost::forward<A3>( a3 ),
  409. boost::forward<A4>( a4 ),
  410. boost::forward<A5>( a5 ),
  411. boost::forward<A6>( a6 )
  412. );
  413. pd->set_initialized();
  414. T * pt2 = static_cast< T* >( pv );
  415. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  416. return boost::shared_ptr< T >( pt, pt2 );
  417. }
  418. template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
  419. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6 )
  420. {
  421. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  422. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  423. void * pv = pd->address();
  424. ::new( pv ) T(
  425. boost::forward<A1>( a1 ),
  426. boost::forward<A2>( a2 ),
  427. boost::forward<A3>( a3 ),
  428. boost::forward<A4>( a4 ),
  429. boost::forward<A5>( a5 ),
  430. boost::forward<A6>( a6 )
  431. );
  432. pd->set_initialized();
  433. T * pt2 = static_cast< T* >( pv );
  434. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  435. return boost::shared_ptr< T >( pt, pt2 );
  436. }
  437. template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
  438. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
  439. {
  440. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  441. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  442. void * pv = pd->address();
  443. ::new( pv ) T(
  444. boost::forward<A1>( a1 ),
  445. boost::forward<A2>( a2 ),
  446. boost::forward<A3>( a3 ),
  447. boost::forward<A4>( a4 ),
  448. boost::forward<A5>( a5 ),
  449. boost::forward<A6>( a6 ),
  450. boost::forward<A7>( a7 )
  451. );
  452. pd->set_initialized();
  453. T * pt2 = static_cast< T* >( pv );
  454. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  455. return boost::shared_ptr< T >( pt, pt2 );
  456. }
  457. template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
  458. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7 )
  459. {
  460. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  461. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  462. void * pv = pd->address();
  463. ::new( pv ) T(
  464. boost::forward<A1>( a1 ),
  465. boost::forward<A2>( a2 ),
  466. boost::forward<A3>( a3 ),
  467. boost::forward<A4>( a4 ),
  468. boost::forward<A5>( a5 ),
  469. boost::forward<A6>( a6 ),
  470. boost::forward<A7>( a7 )
  471. );
  472. pd->set_initialized();
  473. T * pt2 = static_cast< T* >( pv );
  474. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  475. return boost::shared_ptr< T >( pt, pt2 );
  476. }
  477. template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
  478. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
  479. {
  480. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  481. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  482. void * pv = pd->address();
  483. ::new( pv ) T(
  484. boost::forward<A1>( a1 ),
  485. boost::forward<A2>( a2 ),
  486. boost::forward<A3>( a3 ),
  487. boost::forward<A4>( a4 ),
  488. boost::forward<A5>( a5 ),
  489. boost::forward<A6>( a6 ),
  490. boost::forward<A7>( a7 ),
  491. boost::forward<A8>( a8 )
  492. );
  493. pd->set_initialized();
  494. T * pt2 = static_cast< T* >( pv );
  495. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  496. return boost::shared_ptr< T >( pt, pt2 );
  497. }
  498. template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
  499. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8 )
  500. {
  501. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  502. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  503. void * pv = pd->address();
  504. ::new( pv ) T(
  505. boost::forward<A1>( a1 ),
  506. boost::forward<A2>( a2 ),
  507. boost::forward<A3>( a3 ),
  508. boost::forward<A4>( a4 ),
  509. boost::forward<A5>( a5 ),
  510. boost::forward<A6>( a6 ),
  511. boost::forward<A7>( a7 ),
  512. boost::forward<A8>( a8 )
  513. );
  514. pd->set_initialized();
  515. T * pt2 = static_cast< T* >( pv );
  516. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  517. return boost::shared_ptr< T >( pt, pt2 );
  518. }
  519. template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
  520. typename boost::detail::sp_if_not_array< T >::type make_shared( BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
  521. {
  522. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ) );
  523. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  524. void * pv = pd->address();
  525. ::new( pv ) T(
  526. boost::forward<A1>( a1 ),
  527. boost::forward<A2>( a2 ),
  528. boost::forward<A3>( a3 ),
  529. boost::forward<A4>( a4 ),
  530. boost::forward<A5>( a5 ),
  531. boost::forward<A6>( a6 ),
  532. boost::forward<A7>( a7 ),
  533. boost::forward<A8>( a8 ),
  534. boost::forward<A9>( a9 )
  535. );
  536. pd->set_initialized();
  537. T * pt2 = static_cast< T* >( pv );
  538. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  539. return boost::shared_ptr< T >( pt, pt2 );
  540. }
  541. template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
  542. typename boost::detail::sp_if_not_array< T >::type allocate_shared( A const & a, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(A4) a4, BOOST_FWD_REF(A5) a5, BOOST_FWD_REF(A6) a6, BOOST_FWD_REF(A7) a7, BOOST_FWD_REF(A8) a8, BOOST_FWD_REF(A9) a9 )
  543. {
  544. boost::shared_ptr< T > pt( static_cast< T* >( 0 ), BOOST_SP_MSD( T ), a );
  545. boost::detail::sp_ms_deleter< T > * pd = static_cast<boost::detail::sp_ms_deleter< T > *>( pt._internal_get_untyped_deleter() );
  546. void * pv = pd->address();
  547. ::new( pv ) T(
  548. boost::forward<A1>( a1 ),
  549. boost::forward<A2>( a2 ),
  550. boost::forward<A3>( a3 ),
  551. boost::forward<A4>( a4 ),
  552. boost::forward<A5>( a5 ),
  553. boost::forward<A6>( a6 ),
  554. boost::forward<A7>( a7 ),
  555. boost::forward<A8>( a8 ),
  556. boost::forward<A9>( a9 )
  557. );
  558. pd->set_initialized();
  559. T * pt2 = static_cast< T* >( pv );
  560. boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
  561. return boost::shared_ptr< T >( pt, pt2 );
  562. }
  563. #endif // !defined( BOOST_NO_CXX11_VARIADIC_TEMPLATES ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
  564. #undef BOOST_SP_MSD
  565. } // namespace boost
  566. #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_OBJECT_HPP_INCLUDED