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