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 template< class T
> T
forward( T t
)
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();
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();
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
);
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();
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();
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
);
504 #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED