1 #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
\r
2 #define BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
\r
6 // Copyright (c) 2007, 2008 Peter Dimov
\r
8 // Distributed under the Boost Software License, Version 1.0.
\r
9 // See accompanying file LICENSE_1_0.txt or copy at
\r
10 // http://www.boost.org/LICENSE_1_0.txt
\r
12 // See http://www.boost.org/libs/smart_ptr/make_shared.html
\r
13 // for documentation.
\r
15 #include <boost/config.hpp>
\r
16 #include <boost/smart_ptr/shared_ptr.hpp>
\r
17 #include <boost/type_traits/type_with_alignment.hpp>
\r
18 #include <boost/type_traits/alignment_of.hpp>
\r
28 template< std::size_t N, std::size_t A > struct sp_aligned_storage
\r
33 typename boost::type_with_alignment< A >::type align_;
\r
37 template< class T > class sp_ms_deleter
\r
41 typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
\r
44 storage_type storage_;
\r
52 reinterpret_cast< T* >( storage_.data_ )->~T();
\r
53 initialized_ = false;
\r
59 sp_ms_deleter(): initialized_( false )
\r
63 // optimization: do not copy storage_
\r
64 sp_ms_deleter( sp_ms_deleter const & ): initialized_( false )
\r
73 void operator()( T * )
\r
80 return storage_.data_;
\r
83 void set_initialized()
\r
85 initialized_ = true;
\r
89 template< class T > T forward( T t )
\r
94 } // namespace detail
\r
96 // Zero-argument versions
\r
98 // Used even when variadic templates are available because of the new T() vs new T issue
\r
100 template< class T > boost::shared_ptr< T > make_shared()
\r
102 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
104 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
106 void * pv = pd->address();
\r
109 pd->set_initialized();
\r
111 T * pt2 = static_cast< T* >( pv );
\r
113 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
114 return boost::shared_ptr< T >( pt, pt2 );
\r
117 template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
\r
119 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
121 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
123 void * pv = pd->address();
\r
126 pd->set_initialized();
\r
128 T * pt2 = static_cast< T* >( pv );
\r
130 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
131 return boost::shared_ptr< T >( pt, pt2 );
\r
134 #if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
\r
136 // Variadic templates, rvalue reference
\r
138 template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
\r
140 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
142 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
144 void * pv = pd->address();
\r
146 ::new( pv ) T( detail::forward<Args>( args )... );
\r
147 pd->set_initialized();
\r
149 T * pt2 = static_cast< T* >( pv );
\r
151 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
152 return boost::shared_ptr< T >( pt, pt2 );
\r
155 template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
\r
157 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
159 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
161 void * pv = pd->address();
\r
163 ::new( pv ) T( detail::forward<Args>( args )... );
\r
164 pd->set_initialized();
\r
166 T * pt2 = static_cast< T* >( pv );
\r
168 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
169 return boost::shared_ptr< T >( pt, pt2 );
\r
176 template< class T, class A1 >
\r
177 boost::shared_ptr< T > make_shared( A1 const & a1 )
\r
179 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
181 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
183 void * pv = pd->address();
\r
185 ::new( pv ) T( a1 );
\r
186 pd->set_initialized();
\r
188 T * pt2 = static_cast< T* >( pv );
\r
190 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
191 return boost::shared_ptr< T >( pt, pt2 );
\r
194 template< class T, class A, class A1 >
\r
195 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
\r
197 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
199 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
201 void * pv = pd->address();
\r
203 ::new( pv ) T( a1 );
\r
204 pd->set_initialized();
\r
206 T * pt2 = static_cast< T* >( pv );
\r
208 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
209 return boost::shared_ptr< T >( pt, pt2 );
\r
212 template< class T, class A1, class A2 >
\r
213 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
\r
215 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
217 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
219 void * pv = pd->address();
\r
221 ::new( pv ) T( a1, a2 );
\r
222 pd->set_initialized();
\r
224 T * pt2 = static_cast< T* >( pv );
\r
226 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
227 return boost::shared_ptr< T >( pt, pt2 );
\r
230 template< class T, class A, class A1, class A2 >
\r
231 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
\r
233 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
235 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
237 void * pv = pd->address();
\r
239 ::new( pv ) T( a1, a2 );
\r
240 pd->set_initialized();
\r
242 T * pt2 = static_cast< T* >( pv );
\r
244 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
245 return boost::shared_ptr< T >( pt, pt2 );
\r
248 template< class T, class A1, class A2, class A3 >
\r
249 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
\r
251 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
253 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
255 void * pv = pd->address();
\r
257 ::new( pv ) T( a1, a2, a3 );
\r
258 pd->set_initialized();
\r
260 T * pt2 = static_cast< T* >( pv );
\r
262 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
263 return boost::shared_ptr< T >( pt, pt2 );
\r
266 template< class T, class A, class A1, class A2, class A3 >
\r
267 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
\r
269 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
271 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
273 void * pv = pd->address();
\r
275 ::new( pv ) T( a1, a2, a3 );
\r
276 pd->set_initialized();
\r
278 T * pt2 = static_cast< T* >( pv );
\r
280 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
281 return boost::shared_ptr< T >( pt, pt2 );
\r
284 template< class T, class A1, class A2, class A3, class A4 >
\r
285 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
\r
287 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
289 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
291 void * pv = pd->address();
\r
293 ::new( pv ) T( a1, a2, a3, a4 );
\r
294 pd->set_initialized();
\r
296 T * pt2 = static_cast< T* >( pv );
\r
298 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
299 return boost::shared_ptr< T >( pt, pt2 );
\r
302 template< class T, class A, class A1, class A2, class A3, class A4 >
\r
303 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
\r
305 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
307 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
309 void * pv = pd->address();
\r
311 ::new( pv ) T( a1, a2, a3, a4 );
\r
312 pd->set_initialized();
\r
314 T * pt2 = static_cast< T* >( pv );
\r
316 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
317 return boost::shared_ptr< T >( pt, pt2 );
\r
320 template< class T, class A1, class A2, class A3, class A4, class A5 >
\r
321 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
\r
323 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
325 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
327 void * pv = pd->address();
\r
329 ::new( pv ) T( a1, a2, a3, a4, a5 );
\r
330 pd->set_initialized();
\r
332 T * pt2 = static_cast< T* >( pv );
\r
334 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
335 return boost::shared_ptr< T >( pt, pt2 );
\r
338 template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
\r
339 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
\r
341 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
343 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
345 void * pv = pd->address();
\r
347 ::new( pv ) T( a1, a2, a3, a4, a5 );
\r
348 pd->set_initialized();
\r
350 T * pt2 = static_cast< T* >( pv );
\r
352 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
353 return boost::shared_ptr< T >( pt, pt2 );
\r
356 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
\r
357 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
\r
359 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
361 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
363 void * pv = pd->address();
\r
365 ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
\r
366 pd->set_initialized();
\r
368 T * pt2 = static_cast< T* >( pv );
\r
370 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
371 return boost::shared_ptr< T >( pt, pt2 );
\r
374 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
\r
375 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 )
\r
377 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
379 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
381 void * pv = pd->address();
\r
383 ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
\r
384 pd->set_initialized();
\r
386 T * pt2 = static_cast< T* >( pv );
\r
388 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
389 return boost::shared_ptr< T >( pt, pt2 );
\r
392 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
\r
393 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 )
\r
395 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
397 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
399 void * pv = pd->address();
\r
401 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
\r
402 pd->set_initialized();
\r
404 T * pt2 = static_cast< T* >( pv );
\r
406 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
407 return boost::shared_ptr< T >( pt, pt2 );
\r
410 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
\r
411 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 )
\r
413 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
415 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
417 void * pv = pd->address();
\r
419 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
\r
420 pd->set_initialized();
\r
422 T * pt2 = static_cast< T* >( pv );
\r
424 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
425 return boost::shared_ptr< T >( pt, pt2 );
\r
428 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
\r
429 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 )
\r
431 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
433 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
435 void * pv = pd->address();
\r
437 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
\r
438 pd->set_initialized();
\r
440 T * pt2 = static_cast< T* >( pv );
\r
442 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
443 return boost::shared_ptr< T >( pt, pt2 );
\r
446 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
\r
447 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 )
\r
449 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
451 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
453 void * pv = pd->address();
\r
455 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
\r
456 pd->set_initialized();
\r
458 T * pt2 = static_cast< T* >( pv );
\r
460 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
461 return boost::shared_ptr< T >( pt, pt2 );
\r
464 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
\r
465 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 )
\r
467 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
\r
469 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
471 void * pv = pd->address();
\r
473 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
\r
474 pd->set_initialized();
\r
476 T * pt2 = static_cast< T* >( pv );
\r
478 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
479 return boost::shared_ptr< T >( pt, pt2 );
\r
482 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
\r
483 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 )
\r
485 boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
\r
487 detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
\r
489 void * pv = pd->address();
\r
491 ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
\r
492 pd->set_initialized();
\r
494 T * pt2 = static_cast< T* >( pv );
\r
496 boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
\r
497 return boost::shared_ptr< T >( pt, pt2 );
\r
502 } // namespace boost
\r
504 #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
\r