]> git.lyx.org Git - lyx.git/blob - boost/boost/smart_ptr/make_shared.hpp
Make the default format translatable, and load the cite formats in
[lyx.git] / boost / boost / smart_ptr / make_shared.hpp
1 #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED
2 #define BOOST_SMART_PTR_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/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>
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     // optimization: do not copy storage_
64     sp_ms_deleter( sp_ms_deleter const & ): initialized_( false )
65     {
66     }
67
68     ~sp_ms_deleter()
69     {
70         destroy();
71     }
72
73     void operator()( T * )
74     {
75         destroy();
76     }
77
78     void * address()
79     {
80         return storage_.data_;
81     }
82
83     void set_initialized()
84     {
85         initialized_ = true;
86     }
87 };
88
89 #if defined( BOOST_HAS_RVALUE_REFS )
90 template< class T > T&& forward( T &&t )
91 {
92     return t;
93 }
94 #endif
95
96 } // namespace detail
97
98 // Zero-argument versions
99 //
100 // Used even when variadic templates are available because of the new T() vs new T issue
101
102 template< class T > boost::shared_ptr< T > make_shared()
103 {
104     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
105
106     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
107
108     void * pv = pd->address();
109
110     ::new( pv ) T();
111     pd->set_initialized();
112
113     T * pt2 = static_cast< T* >( pv );
114
115     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
116     return boost::shared_ptr< T >( pt, pt2 );
117 }
118
119 template< class T, class A > boost::shared_ptr< T > allocate_shared( A const & a )
120 {
121     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
122
123     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
124
125     void * pv = pd->address();
126
127     ::new( pv ) T();
128     pd->set_initialized();
129
130     T * pt2 = static_cast< T* >( pv );
131
132     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
133     return boost::shared_ptr< T >( pt, pt2 );
134 }
135
136 #if defined( BOOST_HAS_VARIADIC_TMPL ) && defined( BOOST_HAS_RVALUE_REFS )
137
138 // Variadic templates, rvalue reference
139
140 template< class T, class... Args > boost::shared_ptr< T > make_shared( Args && ... args )
141 {
142     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
143
144     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
145
146     void * pv = pd->address();
147
148     ::new( pv ) T( detail::forward<Args>( args )... );
149     pd->set_initialized();
150
151     T * pt2 = static_cast< T* >( pv );
152
153     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
154     return boost::shared_ptr< T >( pt, pt2 );
155 }
156
157 template< class T, class A, class... Args > boost::shared_ptr< T > allocate_shared( A const & a, Args && ... args )
158 {
159     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
160
161     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
162
163     void * pv = pd->address();
164
165     ::new( pv ) T( detail::forward<Args>( args )... );
166     pd->set_initialized();
167
168     T * pt2 = static_cast< T* >( pv );
169
170     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
171     return boost::shared_ptr< T >( pt, pt2 );
172 }
173
174 #else
175
176 // C++03 version
177
178 template< class T, class A1 >
179 boost::shared_ptr< T > make_shared( A1 const & a1 )
180 {
181     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
182
183     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
184
185     void * pv = pd->address();
186
187     ::new( pv ) T( a1 );
188     pd->set_initialized();
189
190     T * pt2 = static_cast< T* >( pv );
191
192     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
193     return boost::shared_ptr< T >( pt, pt2 );
194 }
195
196 template< class T, class A, class A1 >
197 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1 )
198 {
199     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
200
201     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
202
203     void * pv = pd->address();
204
205     ::new( pv ) T( a1 );
206     pd->set_initialized();
207
208     T * pt2 = static_cast< T* >( pv );
209
210     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
211     return boost::shared_ptr< T >( pt, pt2 );
212 }
213
214 template< class T, class A1, class A2 >
215 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2 )
216 {
217     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
218
219     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
220
221     void * pv = pd->address();
222
223     ::new( pv ) T( a1, a2 );
224     pd->set_initialized();
225
226     T * pt2 = static_cast< T* >( pv );
227
228     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
229     return boost::shared_ptr< T >( pt, pt2 );
230 }
231
232 template< class T, class A, class A1, class A2 >
233 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2 )
234 {
235     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
236
237     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
238
239     void * pv = pd->address();
240
241     ::new( pv ) T( a1, a2 );
242     pd->set_initialized();
243
244     T * pt2 = static_cast< T* >( pv );
245
246     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
247     return boost::shared_ptr< T >( pt, pt2 );
248 }
249
250 template< class T, class A1, class A2, class A3 >
251 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3 )
252 {
253     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
254
255     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
256
257     void * pv = pd->address();
258
259     ::new( pv ) T( a1, a2, a3 );
260     pd->set_initialized();
261
262     T * pt2 = static_cast< T* >( pv );
263
264     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
265     return boost::shared_ptr< T >( pt, pt2 );
266 }
267
268 template< class T, class A, class A1, class A2, class A3 >
269 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3 )
270 {
271     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
272
273     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
274
275     void * pv = pd->address();
276
277     ::new( pv ) T( a1, a2, a3 );
278     pd->set_initialized();
279
280     T * pt2 = static_cast< T* >( pv );
281
282     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
283     return boost::shared_ptr< T >( pt, pt2 );
284 }
285
286 template< class T, class A1, class A2, class A3, class A4 >
287 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
288 {
289     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
290
291     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
292
293     void * pv = pd->address();
294
295     ::new( pv ) T( a1, a2, a3, a4 );
296     pd->set_initialized();
297
298     T * pt2 = static_cast< T* >( pv );
299
300     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
301     return boost::shared_ptr< T >( pt, pt2 );
302 }
303
304 template< class T, class A, class A1, class A2, class A3, class A4 >
305 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 )
306 {
307     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
308
309     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
310
311     void * pv = pd->address();
312
313     ::new( pv ) T( a1, a2, a3, a4 );
314     pd->set_initialized();
315
316     T * pt2 = static_cast< T* >( pv );
317
318     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
319     return boost::shared_ptr< T >( pt, pt2 );
320 }
321
322 template< class T, class A1, class A2, class A3, class A4, class A5 >
323 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
324 {
325     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
326
327     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
328
329     void * pv = pd->address();
330
331     ::new( pv ) T( a1, a2, a3, a4, a5 );
332     pd->set_initialized();
333
334     T * pt2 = static_cast< T* >( pv );
335
336     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
337     return boost::shared_ptr< T >( pt, pt2 );
338 }
339
340 template< class T, class A, class A1, class A2, class A3, class A4, class A5 >
341 boost::shared_ptr< T > allocate_shared( A const & a, A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 )
342 {
343     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
344
345     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
346
347     void * pv = pd->address();
348
349     ::new( pv ) T( a1, a2, a3, a4, a5 );
350     pd->set_initialized();
351
352     T * pt2 = static_cast< T* >( pv );
353
354     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
355     return boost::shared_ptr< T >( pt, pt2 );
356 }
357
358 template< class T, class A1, class A2, class A3, class A4, class A5, class A6 >
359 boost::shared_ptr< T > make_shared( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 )
360 {
361     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
362
363     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
364
365     void * pv = pd->address();
366
367     ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
368     pd->set_initialized();
369
370     T * pt2 = static_cast< T* >( pv );
371
372     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
373     return boost::shared_ptr< T >( pt, pt2 );
374 }
375
376 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6 >
377 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 )
378 {
379     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
380
381     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
382
383     void * pv = pd->address();
384
385     ::new( pv ) T( a1, a2, a3, a4, a5, a6 );
386     pd->set_initialized();
387
388     T * pt2 = static_cast< T* >( pv );
389
390     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
391     return boost::shared_ptr< T >( pt, pt2 );
392 }
393
394 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
395 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 )
396 {
397     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
398
399     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
400
401     void * pv = pd->address();
402
403     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
404     pd->set_initialized();
405
406     T * pt2 = static_cast< T* >( pv );
407
408     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
409     return boost::shared_ptr< T >( pt, pt2 );
410 }
411
412 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7 >
413 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 )
414 {
415     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
416
417     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
418
419     void * pv = pd->address();
420
421     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7 );
422     pd->set_initialized();
423
424     T * pt2 = static_cast< T* >( pv );
425
426     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
427     return boost::shared_ptr< T >( pt, pt2 );
428 }
429
430 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
431 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 )
432 {
433     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
434
435     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
436
437     void * pv = pd->address();
438
439     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
440     pd->set_initialized();
441
442     T * pt2 = static_cast< T* >( pv );
443
444     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
445     return boost::shared_ptr< T >( pt, pt2 );
446 }
447
448 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 >
449 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 )
450 {
451     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
452
453     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
454
455     void * pv = pd->address();
456
457     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 );
458     pd->set_initialized();
459
460     T * pt2 = static_cast< T* >( pv );
461
462     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
463     return boost::shared_ptr< T >( pt, pt2 );
464 }
465
466 template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
467 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 )
468 {
469     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >() );
470
471     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
472
473     void * pv = pd->address();
474
475     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
476     pd->set_initialized();
477
478     T * pt2 = static_cast< T* >( pv );
479
480     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
481     return boost::shared_ptr< T >( pt, pt2 );
482 }
483
484 template< class T, class A, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 >
485 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 )
486 {
487     boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::sp_ms_deleter< T >(), a );
488
489     detail::sp_ms_deleter< T > * pd = boost::get_deleter< detail::sp_ms_deleter< T > >( pt );
490
491     void * pv = pd->address();
492
493     ::new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
494     pd->set_initialized();
495
496     T * pt2 = static_cast< T* >( pv );
497
498     boost::detail::sp_enable_shared_from_this( &pt, pt2, pt2 );
499     return boost::shared_ptr< T >( pt, pt2 );
500 }
501
502 #endif
503
504 } // namespace boost
505
506 #endif // #ifndef BOOST_SMART_PTR_MAKE_SHARED_HPP_INCLUDED