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