make_shared_object.hpp 24 KB

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