00001 #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <boost/config.hpp>
00016 #include <boost/smart_ptr/shared_ptr.hpp>
00017 #include <boost/type_traits/type_with_alignment.hpp>
00018 #include <boost/type_traits/alignment_of.hpp>
00019 #include <cstddef>
00020 #include <new>
00021
00022 namespace boost
00023 {
00024
00025 namespace detail
00026 {
00027
00028 template< std::size_t N, std::size_t A > struct sp_aligned_storage
00029 {
00030 union type
00031 {
00032 char data_[ N ];
00033 typename boost::type_with_alignment< A >::type align_;
00034 };
00035 };
00036
00037 template< class T > class sp_ms_deleter
00038 {
00039 private:
00040
00041 typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
00042
00043 bool initialized_;
00044 storage_type storage_;
00045
00046 private:
00047
00048 void destroy()
00049 {
00050 if( initialized_ )
00051 {
00052 reinterpret_cast< T* >( storage_.data_ )->~T();
00053 initialized_ = false;
00054 }
00055 }
00056
00057 public:
00058
00059 sp_ms_deleter(): initialized_( false )
00060 {
00061 }
00062
00063
00064 sp_ms_deleter( sp_ms_deleter const & ): initialized_( false )
00065 {
00066 }
00067
00068 ~sp_ms_deleter()
00069 {
00070 destroy();
00071 }
00072
00073 void operator()( T * )
00074 {
00075 destroy();
00076 }
00077
00078 void * address()
00079 {
00080 return storage_.data_;
00081 }
00082
00083 void set_initialized()
00084 {
00085 initialized_ = true;
00086 }
00087 };
00088
00089 template< class T > T forward( T t )
00090 {
00091 return t;
00092 }
00093
00094 }
00095
00096
00097
00098
00099
00100 template< class T > boost::shared_ptr< T > make_shared()
00101 {
00102 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00103
00104 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00105
00106 void * pv = pd->address();
00107
00108 ::new( pv ) T();
00109 pd->set_initialized();
00110
00111 T * pt2 = static_cast< T* >( pv );
00112
00113 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00114 return boost::shared_ptr< T >( pt, pt2 );
00115 }
00116
00117 template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
00118 {
00119 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00120
00121 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00122
00123 void * pv = pd->address();
00124
00125 ::new( pv ) T();
00126 pd->set_initialized();
00127
00128 T * pt2 = static_cast< T* >( pv );
00129
00130 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00131 return boost::shared_ptr< T >( pt, pt2 );
00132 }
00133
00134 #if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
00135
00136
00137
00138 template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
00139 {
00140 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00141
00142 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00143
00144 void * pv = pd->address();
00145
00146 ::new( pv ) T( detail::forward<Args>( args )... );
00147 pd->set_initialized();
00148
00149 T * pt2 = static_cast< T* >( pv );
00150
00151 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00152 return boost::shared_ptr< T >( pt, pt2 );
00153 }
00154
00155 template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
00156 {
00157 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00158
00159 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00160
00161 void * pv = pd->address();
00162
00163 ::new( pv ) T( detail::forward<Args>( args )... );
00164 pd->set_initialized();
00165
00166 T * pt2 = static_cast< T* >( pv );
00167
00168 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00169 return boost::shared_ptr< T >( pt, pt2 );
00170 }
00171
00172 #else
00173
00174
00175
00176 template< class T, class A1 >
00177 boost::shared_ptr< T > make_shared( A1 const & a1 )
00178 {
00179 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00180
00181 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00182
00183 void * pv = pd->address();
00184
00185 ::new( pv ) T( a1 );
00186 pd->set_initialized();
00187
00188 T * pt2 = static_cast< T* >( pv );
00189
00190 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00191 return boost::shared_ptr< T >( pt, pt2 );
00192 }
00193
00194 template< class T, class A, class A1 >
00195 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
00196 {
00197 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00198
00199 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00200
00201 void * pv = pd->address();
00202
00203 ::new( pv ) T( a1 );
00204 pd->set_initialized();
00205
00206 T * pt2 = static_cast< T* >( pv );
00207
00208 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00209 return boost::shared_ptr< T >( pt, pt2 );
00210 }
00211
00212 template< class T, class A1, class A2 >
00213 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
00214 {
00215 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00216
00217 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00218
00219 void * pv = pd->address();
00220
00221 ::new( pv ) T( a1, a2 );
00222 pd->set_initialized();
00223
00224 T * pt2 = static_cast< T* >( pv );
00225
00226 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00227 return boost::shared_ptr< T >( pt, pt2 );
00228 }
00229
00230 template< class T, class A, class A1, class A2 >
00231 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
00232 {
00233 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00234
00235 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00236
00237 void * pv = pd->address();
00238
00239 ::new( pv ) T( a1, a2 );
00240 pd->set_initialized();
00241
00242 T * pt2 = static_cast< T* >( pv );
00243
00244 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00245 return boost::shared_ptr< T >( pt, pt2 );
00246 }
00247
00248 template< class T, class A1, class A2, class A3 >
00249 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
00250 {
00251 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00252
00253 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00254
00255 void * pv = pd->address();
00256
00257 ::new( pv ) T( a1, a2, a3 );
00258 pd->set_initialized();
00259
00260 T * pt2 = static_cast< T* >( pv );
00261
00262 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00263 return boost::shared_ptr< T >( pt, pt2 );
00264 }
00265
00266 template< class T, class A, class A1, class A2, class A3 >
00267 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
00268 {
00269 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00270
00271 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00272
00273 void * pv = pd->address();
00274
00275 ::new( pv ) T( a1, a2, a3 );
00276 pd->set_initialized();
00277
00278 T * pt2 = static_cast< T* >( pv );
00279
00280 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00281 return boost::shared_ptr< T >( pt, pt2 );
00282 }
00283
00284 template< class T, class A1, class A2, class A3, class A4 >
00285 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
00286 {
00287 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00288
00289 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00290
00291 void * pv = pd->address();
00292
00293 ::new( pv ) T( a1, a2, a3, a4 );
00294 pd->set_initialized();
00295
00296 T * pt2 = static_cast< T* >( pv );
00297
00298 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00299 return boost::shared_ptr< T >( pt, pt2 );
00300 }
00301
00302 template< class T, class A, class A1, class A2, class A3, class A4 >
00303 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
00304 {
00305 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00306
00307 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00308
00309 void * pv = pd->address();
00310
00311 ::new( pv ) T( a1, a2, a3, a4 );
00312 pd->set_initialized();
00313
00314 T * pt2 = static_cast< T* >( pv );
00315
00316 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00317 return boost::shared_ptr< T >( pt, pt2 );
00318 }
00319
00320 template< class T, class A1, class A2, class A3, class A4, class A5 >
00321 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
00322 {
00323 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00324
00325 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00326
00327 void * pv = pd->address();
00328
00329 ::new( pv ) T( a1, a2, a3, a4, a5 );
00330 pd->set_initialized();
00331
00332 T * pt2 = static_cast< T* >( pv );
00333
00334 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00335 return boost::shared_ptr< T >( pt, pt2 );
00336 }
00337
00338 template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
00339 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
00340 {
00341 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00342
00343 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00344
00345 void * pv = pd->address();
00346
00347 ::new( pv ) T( a1, a2, a3, a4, a5 );
00348 pd->set_initialized();
00349
00350 T * pt2 = static_cast< T* >( pv );
00351
00352 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00353 return boost::shared_ptr< T >( pt, pt2 );
00354 }
00355
00356 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
00357 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
00358 {
00359 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00360
00361 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00362
00363 void * pv = pd->address();
00364
00365 ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
00366 pd->set_initialized();
00367
00368 T * pt2 = static_cast< T* >( pv );
00369
00370 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00371 return boost::shared_ptr< T >( pt, pt2 );
00372 }
00373
00374 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
00375 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 )
00376 {
00377 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00378
00379 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00380
00381 void * pv = pd->address();
00382
00383 ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
00384 pd->set_initialized();
00385
00386 T * pt2 = static_cast< T* >( pv );
00387
00388 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00389 return boost::shared_ptr< T >( pt, pt2 );
00390 }
00391
00392 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
00393 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 )
00394 {
00395 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00396
00397 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00398
00399 void * pv = pd->address();
00400
00401 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
00402 pd->set_initialized();
00403
00404 T * pt2 = static_cast< T* >( pv );
00405
00406 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00407 return boost::shared_ptr< T >( pt, pt2 );
00408 }
00409
00410 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
00411 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 )
00412 {
00413 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00414
00415 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00416
00417 void * pv = pd->address();
00418
00419 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
00420 pd->set_initialized();
00421
00422 T * pt2 = static_cast< T* >( pv );
00423
00424 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00425 return boost::shared_ptr< T >( pt, pt2 );
00426 }
00427
00428 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
00429 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 )
00430 {
00431 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00432
00433 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00434
00435 void * pv = pd->address();
00436
00437 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
00438 pd->set_initialized();
00439
00440 T * pt2 = static_cast< T* >( pv );
00441
00442 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00443 return boost::shared_ptr< T >( pt, pt2 );
00444 }
00445
00446 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
00447 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 )
00448 {
00449 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00450
00451 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00452
00453 void * pv = pd->address();
00454
00455 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
00456 pd->set_initialized();
00457
00458 T * pt2 = static_cast< T* >( pv );
00459
00460 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00461 return boost::shared_ptr< T >( pt, pt2 );
00462 }
00463
00464 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
00465 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 )
00466 {
00467 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
00468
00469 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00470
00471 void * pv = pd->address();
00472
00473 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
00474 pd->set_initialized();
00475
00476 T * pt2 = static_cast< T* >( pv );
00477
00478 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00479 return boost::shared_ptr< T >( pt, pt2 );
00480 }
00481
00482 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
00483 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 )
00484 {
00485 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
00486
00487 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
00488
00489 void * pv = pd->address();
00490
00491 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
00492 pd->set_initialized();
00493
00494 T * pt2 = static_cast< T* >( pv );
00495
00496 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
00497 return boost::shared_ptr< T >( pt, pt2 );
00498 }
00499
00500 #endif
00501
00502 }
00503
00504 #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED