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