Merge c:/dyninst/pc_bluegene/dyninst into dyn_pc_integration
[dyninst.git] / external / boost / make_shared.hpp
1 #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED
2 #define BOOST_MAKE_SHARED_HPP_INCLUDED
3
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
11 //
12 //  See http://www.boost.org/libs/smart_ptr/make_shared.html
13 //  for documentation.
14
15 #include <boost/config.hpp>
16 #include <boost/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>
21
22 namespace boost
23 {
24
25 namespace detail
26 {
27
28 template< std::size_t N, std::size_t A > struct sp_aligned_storage
29 {
30     union type
31     {
32         char data_[ N ];
33         typename boost::type_with_alignment< A >::type align_;
34     };
35 };
36
37 template< class T > class sp_ms_deleter
38 {
39 private:
40
41     typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
42
43     bool initialized_;
44     storage_type storage_;
45
46 private:
47
48     void destroy()
49     {
50         if( initialized_ )
51         {
52             reinterpret_cast< T* >( storage_.data_ )->~T();
53             initialized_ = false;
54         }
55     }
56
57 public:
58
59     sp_ms_deleter(): initialized_( false )
60     {
61     }
62
63     ~sp_ms_deleter()
64     {
65         destroy();
66     }
67
68     void operator()( T * )
69     {
70         destroy();
71     }
72
73     void * address()
74     {
75         return storage_.data_;
76     }
77
78     void set_initialized()
79     {
80         initialized_ = true;
81     }
82 };
83
84 template< class T > T forward( T t )
85 {
86     return t;
87 }
88
89 } // namespace detail
90
91 // Zero-argument versions
92 //
93 // Used even when variadic templates are available because of the new T() vs new T issue
94
95 template< class T > boost::shared_ptr< T > make_shared()
96 {
97     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
98
99     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
100
101     void * pv = pd->address();
102
103     new( pv ) T();
104     pd->set_initialized();
105
106     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
107 }
108
109 template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
110 {
111     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
112
113     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
114
115     void * pv = pd->address();
116
117     new( pv ) T();
118     pd->set_initialized();
119
120     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
121 }
122
123 #if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
124
125 // Variadic templates, rvalue reference
126
127 template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
128 {
129     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
130
131     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
132
133     void * pv = pd->address();
134
135     new( pv ) T( detail::forward<Args>( args )... );
136     pd->set_initialized();
137
138     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
139 }
140
141 template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
142 {
143     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
144
145     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
146
147     void * pv = pd->address();
148
149     new( pv ) T( detail::forward<Args>( args )... );
150     pd->set_initialized();
151
152     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
153 }
154
155 #else
156
157 // C++03 version
158
159 template< class T, class A1 >
160 boost::shared_ptr< T > make_shared( A1 const & a1 )
161 {
162     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
163
164     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
165
166     void * pv = pd->address();
167
168     new( pv ) T( a1 );
169     pd->set_initialized();
170
171     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
172 }
173
174 template< class T, class A, class A1 >
175 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
176 {
177     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
178
179     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
180
181     void * pv = pd->address();
182
183     new( pv ) T( a1 );
184     pd->set_initialized();
185
186     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
187 }
188
189 template< class T, class A1, class A2 >
190 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
191 {
192     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
193
194     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
195
196     void * pv = pd->address();
197
198     new( pv ) T( a1, a2 );
199     pd->set_initialized();
200
201     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
202 }
203
204 template< class T, class A, class A1, class A2 >
205 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
206 {
207     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
208
209     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
210
211     void * pv = pd->address();
212
213     new( pv ) T( a1, a2 );
214     pd->set_initialized();
215
216     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
217 }
218
219 template< class T, class A1, class A2, class A3 >
220 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
221 {
222     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
223
224     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
225
226     void * pv = pd->address();
227
228     new( pv ) T( a1, a2, a3 );
229     pd->set_initialized();
230
231     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
232 }
233
234 template< class T, class A, class A1, class A2, class A3 >
235 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
236 {
237     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
238
239     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
240
241     void * pv = pd->address();
242
243     new( pv ) T( a1, a2, a3 );
244     pd->set_initialized();
245
246     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
247 }
248
249 template< class T, class A1, class A2, class A3, class A4 >
250 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
251 {
252     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
253
254     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
255
256     void * pv = pd->address();
257
258     new( pv ) T( a1, a2, a3, a4 );
259     pd->set_initialized();
260
261     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
262 }
263
264 template< class T, class A, class A1, class A2, class A3, class A4 >
265 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
266 {
267     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
268
269     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
270
271     void * pv = pd->address();
272
273     new( pv ) T( a1, a2, a3, a4 );
274     pd->set_initialized();
275
276     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
277 }
278
279 template< class T, class A1, class A2, class A3, class A4, class A5 >
280 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
281 {
282     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
283
284     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
285
286     void * pv = pd->address();
287
288     new( pv ) T( a1, a2, a3, a4, a5 );
289     pd->set_initialized();
290
291     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
292 }
293
294 template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
295 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
296 {
297     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
298
299     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
300
301     void * pv = pd->address();
302
303     new( pv ) T( a1, a2, a3, a4, a5 );
304     pd->set_initialized();
305
306     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
307 }
308
309 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
310 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
311 {
312     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
313
314     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
315
316     void * pv = pd->address();
317
318     new( pv ) T( a1, a2, a3, a4, a5, a6 );
319     pd->set_initialized();
320
321     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
322 }
323
324 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
325 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 )
326 {
327     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
328
329     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
330
331     void * pv = pd->address();
332
333     new( pv ) T( a1, a2, a3, a4, a5, a6 );
334     pd->set_initialized();
335
336     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
337 }
338
339 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
340 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 )
341 {
342     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
343
344     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
345
346     void * pv = pd->address();
347
348     new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
349     pd->set_initialized();
350
351     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
352 }
353
354 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
355 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 )
356 {
357     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
358
359     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
360
361     void * pv = pd->address();
362
363     new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
364     pd->set_initialized();
365
366     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
367 }
368
369 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
370 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 )
371 {
372     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
373
374     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
375
376     void * pv = pd->address();
377
378     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
379     pd->set_initialized();
380
381     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
382 }
383
384 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
385 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 )
386 {
387     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
388
389     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
390
391     void * pv = pd->address();
392
393     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
394     pd->set_initialized();
395
396     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
397 }
398
399 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
400 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 )
401 {
402     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
403
404     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
405
406     void * pv = pd->address();
407
408     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
409     pd->set_initialized();
410
411     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
412 }
413
414 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
415 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 )
416 {
417     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
418
419     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
420
421     void * pv = pd->address();
422
423     new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
424     pd->set_initialized();
425
426     return boost::shared_ptr< T >( pt, static_cast< T* >( pv ) );
427 }
428
429 #endif
430
431 } // namespace boost
432
433 #endif // #ifndef BOOST_MAKE_SHARED_HPP_INCLUDED