1 #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
2 #define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
6 // Copyright (c) 2007, 2008 Peter Dimov
8 // Distributed under the Boost Software License, Version 1.0.
9 // See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt
12 // See http://www.boost.org/libs/smart_ptr/make_shared.html
15 #include <boost/config.hpp>
16 #include <boost/smart_ptr/shared_ptr.hpp>
17 #include <boost/type_traits/type_with_alignment.hpp>
18 #include <boost/type_traits/alignment_of.hpp>
28 template< std::size_t N, std::size_t A > struct sp_aligned_storage
33 typename boost::type_with_alignment< A >::type align_;
37 template< class T > class sp_ms_deleter
41 typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
44 storage_type storage_;
52 reinterpret_cast< T* >( storage_.data_ )->~T();
59 sp_ms_deleter(): initialized_( false )
63 // optimization: do not copy storage_
64 sp_ms_deleter( sp_ms_deleter const & ): initialized_( false )
73 void operator()( T * )
80 return storage_.data_;
83 void set_initialized()
89 #if defined( BOOST_HAS_RVALUE_REFS )
91 template< class T > T&& sp_forward( T & t )
93 return static_cast< T&& >( t );
100 // Zero-argument versions
102 // Used even when variadic templates are available because of the new T() vs new T issue
104 template< class T > boost::shared_ptr< T > make_shared()
106 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
108 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
110 void * pv = pd->address();
113 pd->set_initialized();
115 T * pt2 = static_cast< T* >( pv );
117 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
118 return boost::shared_ptr< T >( pt, pt2 );
121 template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
123 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
125 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
127 void * pv = pd->address();
130 pd->set_initialized();
132 T * pt2 = static_cast< T* >( pv );
134 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
135 return boost::shared_ptr< T >( pt, pt2 );
138 #if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
140 // Variadic templates, rvalue reference
142 template< class T, class Arg1, class... Args > boost::shared_ptr< T > make_shared( Arg1 && arg1, Args && ... args )
144 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
146 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
148 void * pv = pd->address();
150 ::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
151 pd->set_initialized();
153 T * pt2 = static_cast< T* >( pv );
155 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
156 return boost::shared_ptr< T >( pt, pt2 );
159 template< class T, class A, class Arg1, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Arg1 && arg1, Args && ... args )
161 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
163 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
165 void * pv = pd->address();
167 ::new( pv ) T( boost::detail::sp_forward<Arg1>( arg1 ), boost::detail::sp_forward<Args>( args )... );
168 pd->set_initialized();
170 T * pt2 = static_cast< T* >( pv );
172 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
173 return boost::shared_ptr< T >( pt, pt2 );
180 template< class T, class A1 >
181 boost::shared_ptr< T > make_shared( A1 const & a1 )
183 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
185 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
187 void * pv = pd->address();
190 pd->set_initialized();
192 T * pt2 = static_cast< T* >( pv );
194 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
195 return boost::shared_ptr< T >( pt, pt2 );
198 template< class T, class A, class A1 >
199 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
201 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
203 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
205 void * pv = pd->address();
208 pd->set_initialized();
210 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 );
216 template< class T, class A1, class A2 >
217 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
219 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
221 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
223 void * pv = pd->address();
225 ::new( pv ) T( a1, a2 );
226 pd->set_initialized();
228 T * pt2 = static_cast< T* >( pv );
230 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
231 return boost::shared_ptr< T >( pt, pt2 );
234 template< class T, class A, class A1, class A2 >
235 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
237 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
239 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
241 void * pv = pd->address();
243 ::new( pv ) T( a1, a2 );
244 pd->set_initialized();
246 T * pt2 = static_cast< T* >( pv );
248 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
249 return boost::shared_ptr< T >( pt, pt2 );
252 template< class T, class A1, class A2, class A3 >
253 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
255 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
257 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
259 void * pv = pd->address();
261 ::new( pv ) T( a1, a2, a3 );
262 pd->set_initialized();
264 T * pt2 = static_cast< T* >( pv );
266 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
267 return boost::shared_ptr< T >( pt, pt2 );
270 template< class T, class A, class A1, class A2, class A3 >
271 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
273 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
275 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
277 void * pv = pd->address();
279 ::new( pv ) T( a1, a2, a3 );
280 pd->set_initialized();
282 T * pt2 = static_cast< T* >( pv );
284 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
285 return boost::shared_ptr< T >( pt, pt2 );
288 template< class T, class A1, class A2, class A3, class A4 >
289 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
291 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
293 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
295 void * pv = pd->address();
297 ::new( pv ) T( a1, a2, a3, a4 );
298 pd->set_initialized();
300 T * pt2 = static_cast< T* >( pv );
302 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
303 return boost::shared_ptr< T >( pt, pt2 );
306 template< class T, class A, class A1, class A2, class A3, class A4 >
307 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
309 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
311 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
313 void * pv = pd->address();
315 ::new( pv ) T( a1, a2, a3, a4 );
316 pd->set_initialized();
318 T * pt2 = static_cast< T* >( pv );
320 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
321 return boost::shared_ptr< T >( pt, pt2 );
324 template< class T, class A1, class A2, class A3, class A4, class A5 >
325 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
327 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
329 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
331 void * pv = pd->address();
333 ::new( pv ) T( a1, a2, a3, a4, a5 );
334 pd->set_initialized();
336 T * pt2 = static_cast< T* >( pv );
338 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
339 return boost::shared_ptr< T >( pt, pt2 );
342 template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
343 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
345 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
347 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
349 void * pv = pd->address();
351 ::new( pv ) T( a1, a2, a3, a4, a5 );
352 pd->set_initialized();
354 T * pt2 = static_cast< T* >( pv );
356 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
357 return boost::shared_ptr< T >( pt, pt2 );
360 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
361 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
363 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
365 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
367 void * pv = pd->address();
369 ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
370 pd->set_initialized();
372 T * pt2 = static_cast< T* >( pv );
374 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
375 return boost::shared_ptr< T >( pt, pt2 );
378 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
379 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
381 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
383 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
385 void * pv = pd->address();
387 ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
388 pd->set_initialized();
390 T * pt2 = static_cast< T* >( pv );
392 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
393 return boost::shared_ptr< T >( pt, pt2 );
396 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
397 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
399 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
401 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
403 void * pv = pd->address();
405 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
406 pd->set_initialized();
408 T * pt2 = static_cast< T* >( pv );
410 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
411 return boost::shared_ptr< T >( pt, pt2 );
414 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
415 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 )
417 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
419 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
421 void * pv = pd->address();
423 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
424 pd->set_initialized();
426 T * pt2 = static_cast< T* >( pv );
428 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
429 return boost::shared_ptr< T >( pt, pt2 );
432 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
433 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
435 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
437 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
439 void * pv = pd->address();
441 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
442 pd->set_initialized();
444 T * pt2 = static_cast< T* >( pv );
446 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
447 return boost::shared_ptr< T >( pt, pt2 );
450 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
451 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 )
453 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
455 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
457 void * pv = pd->address();
459 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
460 pd->set_initialized();
462 T * pt2 = static_cast< T* >( pv );
464 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
465 return boost::shared_ptr< T >( pt, pt2 );
468 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
469 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
471 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >() );
473 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
475 void * pv = pd->address();
477 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
478 pd->set_initialized();
480 T * pt2 = static_cast< T* >( pv );
482 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
483 return boost::shared_ptr< T >( pt, pt2 );
486 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
487 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9 )
489 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), boost::detail::sp_ms_deleter< T >(), a );
491 boost::detail::sp_ms_deleter< T > * pd = boost::get_deleter< boost::detail::sp_ms_deleter< T > >( pt );
493 void * pv = pd->address();
495 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
496 pd->set_initialized();
498 T * pt2 = static_cast< T* >( pv );
500 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
501 return boost::shared_ptr< T >( pt, pt2 );
508 #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED