make_shared.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
00003 
00004 //  make_shared.hpp
00005 //
00006 //  Copyright (c) 2007, 2008 Peter Dimov
00007 //
00008 //  Distributed under the Boost Software License, Version 1.0.
00009 //  See accompanying file LICENSE_1_0.txt or copy at
00010 //  http://www.boost.org/LICENSE_1_0.txt
00011 //
00012 //  See http://www.boost.org/libs/smart_ptr/make_shared.html
00013 //  for documentation.
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     // optimization: do not copy storage_
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 } // namespace detail
00095 
00096 // Zero-argument versions
00097 //
00098 // Used even when variadic templates are available because of the new T() vs new T issue
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 // Variadic templates, rvalue reference
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 // C++03 version
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 } // namespace boost
00503 
00504 #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29