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 )
90
template< class T > T&& forward( T &&t )
98
// Zero-argument versions
100
// Used even when variadic templates are available because of the new T() vs new T issue
102
template< class T > boost::shared_ptr< T > make_shared()
104
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
106
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
108
void * pv = pd->address();
111
pd->set_initialized();
113
T * pt2 = static_cast< T* >( pv );
115
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
116
return boost::shared_ptr< T >( pt, pt2 );
119
template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
121
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
123
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
125
void * pv = pd->address();
128
pd->set_initialized();
130
T * pt2 = static_cast< T* >( pv );
132
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
133
return boost::shared_ptr< T >( pt, pt2 );
136
#if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
138
// Variadic templates, rvalue reference
140
template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
142
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
144
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
146
void * pv = pd->address();
148
::new( pv ) T( detail::forward<Args>( args )... );
149
pd->set_initialized();
151
T * pt2 = static_cast< T* >( pv );
153
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
154
return boost::shared_ptr< T >( pt, pt2 );
157
template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
159
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
161
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
163
void * pv = pd->address();
165
::new( pv ) T( detail::forward<Args>( args )... );
166
pd->set_initialized();
168
T * pt2 = static_cast< T* >( pv );
170
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
171
return boost::shared_ptr< T >( pt, pt2 );
178
template< class T, class A1 >
179
boost::shared_ptr< T > make_shared( A1 const & a1 )
181
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
183
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
185
void * pv = pd->address();
188
pd->set_initialized();
190
T * pt2 = static_cast< T* >( pv );
192
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
193
return boost::shared_ptr< T >( pt, pt2 );
196
template< class T, class A, class A1 >
197
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
199
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
201
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
203
void * pv = pd->address();
206
pd->set_initialized();
208
T * pt2 = static_cast< T* >( pv );
210
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
211
return boost::shared_ptr< T >( pt, pt2 );
214
template< class T, class A1, class A2 >
215
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
217
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
219
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
221
void * pv = pd->address();
223
::new( pv ) T( a1, a2 );
224
pd->set_initialized();
226
T * pt2 = static_cast< T* >( pv );
228
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
229
return boost::shared_ptr< T >( pt, pt2 );
232
template< class T, class A, class A1, class A2 >
233
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
235
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
237
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
239
void * pv = pd->address();
241
::new( pv ) T( a1, a2 );
242
pd->set_initialized();
244
T * pt2 = static_cast< T* >( pv );
246
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
247
return boost::shared_ptr< T >( pt, pt2 );
250
template< class T, class A1, class A2, class A3 >
251
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
253
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
255
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
257
void * pv = pd->address();
259
::new( pv ) T( a1, a2, a3 );
260
pd->set_initialized();
262
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 );
268
template< class T, class A, class A1, class A2, class A3 >
269
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
271
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
273
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
275
void * pv = pd->address();
277
::new( pv ) T( a1, a2, a3 );
278
pd->set_initialized();
280
T * pt2 = static_cast< T* >( pv );
282
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
283
return boost::shared_ptr< T >( pt, pt2 );
286
template< class T, class A1, class A2, class A3, class A4 >
287
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
289
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
291
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
293
void * pv = pd->address();
295
::new( pv ) T( a1, a2, a3, a4 );
296
pd->set_initialized();
298
T * pt2 = static_cast< T* >( pv );
300
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
301
return boost::shared_ptr< T >( pt, pt2 );
304
template< class T, class A, class A1, class A2, class A3, class A4 >
305
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
307
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
309
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
311
void * pv = pd->address();
313
::new( pv ) T( a1, a2, a3, a4 );
314
pd->set_initialized();
316
T * pt2 = static_cast< T* >( pv );
318
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
319
return boost::shared_ptr< T >( pt, pt2 );
322
template< class T, class A1, class A2, class A3, class A4, class A5 >
323
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
325
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
327
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
329
void * pv = pd->address();
331
::new( pv ) T( a1, a2, a3, a4, a5 );
332
pd->set_initialized();
334
T * pt2 = static_cast< T* >( pv );
336
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
337
return boost::shared_ptr< T >( pt, pt2 );
340
template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
341
boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
343
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
345
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
347
void * pv = pd->address();
349
::new( pv ) T( a1, a2, a3, a4, a5 );
350
pd->set_initialized();
352
T * pt2 = static_cast< T* >( pv );
354
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
355
return boost::shared_ptr< T >( pt, pt2 );
358
template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
359
boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
361
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
363
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
365
void * pv = pd->address();
367
::new( pv ) T( a1, a2, a3, a4, a5, a6 );
368
pd->set_initialized();
370
T * pt2 = static_cast< T* >( pv );
372
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
373
return boost::shared_ptr< T >( pt, pt2 );
376
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
377
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 )
379
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
381
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
383
void * pv = pd->address();
385
::new( pv ) T( a1, a2, a3, a4, a5, a6 );
386
pd->set_initialized();
388
T * pt2 = static_cast< T* >( pv );
390
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
391
return boost::shared_ptr< T >( pt, pt2 );
394
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
395
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 )
397
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
399
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
401
void * pv = pd->address();
403
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
404
pd->set_initialized();
406
T * pt2 = static_cast< T* >( pv );
408
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
409
return boost::shared_ptr< T >( pt, pt2 );
412
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
413
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 )
415
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
417
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
419
void * pv = pd->address();
421
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
422
pd->set_initialized();
424
T * pt2 = static_cast< T* >( pv );
426
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
427
return boost::shared_ptr< T >( pt, pt2 );
430
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
431
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 )
433
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
435
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
437
void * pv = pd->address();
439
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
440
pd->set_initialized();
442
T * pt2 = static_cast< T* >( pv );
444
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
445
return boost::shared_ptr< T >( pt, pt2 );
448
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
449
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 )
451
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
453
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
455
void * pv = pd->address();
457
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
458
pd->set_initialized();
460
T * pt2 = static_cast< T* >( pv );
462
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
463
return boost::shared_ptr< T >( pt, pt2 );
466
template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
467
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 )
469
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
471
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
473
void * pv = pd->address();
475
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
476
pd->set_initialized();
478
T * pt2 = static_cast< T* >( pv );
480
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
481
return boost::shared_ptr< T >( pt, pt2 );
484
template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
485
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 )
487
boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
489
detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
491
void * pv = pd->address();
493
::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
494
pd->set_initialized();
496
T * pt2 = static_cast< T* >( pv );
498
boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
499
return boost::shared_ptr< T >( pt, pt2 );
506
#endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED