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