]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP |
2 | #define BOOST_SIGNALS2_DECONSTRUCT_HPP | |
3 | ||
4 | // deconstruct.hpp | |
5 | // | |
6 | // A factory function for creating a shared_ptr which creates | |
7 | // an object and its owning shared_ptr with one allocation, similar | |
8 | // to make_shared<T>(). It also supports postconstructors | |
9 | // and predestructors through unqualified calls of adl_postconstruct() and | |
10 | // adl_predestruct, relying on argument-dependent | |
11 | // lookup to find the appropriate postconstructor or predestructor. | |
12 | // Passing arguments to postconstructors is also supported. | |
13 | // | |
14 | // based on make_shared.hpp and make_shared_access patch from Michael Marcin | |
15 | // | |
16 | // Copyright (c) 2007, 2008 Peter Dimov | |
17 | // Copyright (c) 2008 Michael Marcin | |
18 | // Copyright (c) 2009 Frank Mori Hess | |
19 | // | |
20 | // Distributed under the Boost Software License, Version 1.0. | |
21 | // See accompanying file LICENSE_1_0.txt or copy at | |
22 | // http://www.boost.org/LICENSE_1_0.txt | |
23 | // | |
24 | // See http://www.boost.org | |
25 | // for more information | |
26 | ||
27 | #include <boost/config.hpp> | |
28 | #include <boost/shared_ptr.hpp> | |
29 | #include <boost/type_traits/alignment_of.hpp> | |
30 | #include <boost/type_traits/remove_const.hpp> | |
31 | #include <boost/type_traits/type_with_alignment.hpp> | |
32 | #include <cstddef> | |
33 | #include <new> | |
34 | ||
35 | namespace boost | |
36 | { | |
37 | template<typename T> class enable_shared_from_this; | |
38 | ||
39 | namespace signals2 | |
40 | { | |
41 | class deconstruct_access; | |
42 | ||
43 | namespace detail | |
44 | { | |
45 | inline void adl_predestruct(...) {} | |
46 | } // namespace detail | |
47 | ||
48 | template<typename T> | |
49 | class postconstructor_invoker | |
50 | { | |
51 | public: | |
52 | operator const shared_ptr<T> & () const | |
53 | { | |
54 | return postconstruct(); | |
55 | } | |
56 | const shared_ptr<T>& postconstruct() const | |
57 | { | |
58 | if(!_postconstructed) | |
59 | { | |
60 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get())); | |
61 | _postconstructed = true; | |
62 | } | |
63 | return _sp; | |
64 | } | |
65 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
66 | template<class... Args> | |
67 | const shared_ptr<T>& postconstruct(Args && ... args) | |
68 | { | |
69 | if(!_postconstructed) | |
70 | { | |
71 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
72 | std::forward<Args>(args)...); | |
73 | _postconstructed = true; | |
74 | } | |
75 | return _sp; | |
76 | } | |
77 | #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
78 | template<typename A1> | |
79 | const shared_ptr<T>& postconstruct(const A1 &a1) const | |
80 | { | |
81 | if(!_postconstructed) | |
82 | { | |
83 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
84 | a1); | |
85 | _postconstructed = true; | |
86 | } | |
87 | return _sp; | |
88 | } | |
89 | template<typename A1, typename A2> | |
90 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2) const | |
91 | { | |
92 | if(!_postconstructed) | |
93 | { | |
94 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
95 | a1, a2); | |
96 | _postconstructed = true; | |
97 | } | |
98 | return _sp; | |
99 | } | |
100 | template<typename A1, typename A2, typename A3> | |
101 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3) const | |
102 | { | |
103 | if(!_postconstructed) | |
104 | { | |
105 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
106 | a1, a2, a3); | |
107 | _postconstructed = true; | |
108 | } | |
109 | return _sp; | |
110 | } | |
111 | template<typename A1, typename A2, typename A3, typename A4> | |
112 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const | |
113 | { | |
114 | if(!_postconstructed) | |
115 | { | |
116 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
117 | a1, a2, a3, a4); | |
118 | _postconstructed = true; | |
119 | } | |
120 | return _sp; | |
121 | } | |
122 | template<typename A1, typename A2, typename A3, typename A4, typename A5> | |
123 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const | |
124 | { | |
125 | if(!_postconstructed) | |
126 | { | |
127 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
128 | a1, a2, a3, a4, a5); | |
129 | _postconstructed = true; | |
130 | } | |
131 | return _sp; | |
132 | } | |
133 | template<typename A1, typename A2, typename A3, typename A4, typename A5, | |
134 | typename A6> | |
135 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, | |
136 | const A6 &a6) const | |
137 | { | |
138 | if(!_postconstructed) | |
139 | { | |
140 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
141 | a1, a2, a3, a4, a5, a6); | |
142 | _postconstructed = true; | |
143 | } | |
144 | return _sp; | |
145 | } | |
146 | template<typename A1, typename A2, typename A3, typename A4, typename A5, | |
147 | typename A6, typename A7> | |
148 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, | |
149 | const A6 &a6, const A7 &a7) const | |
150 | { | |
151 | if(!_postconstructed) | |
152 | { | |
153 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
154 | a1, a2, a3, a4, a5, a6, a7); | |
155 | _postconstructed = true; | |
156 | } | |
157 | return _sp; | |
158 | } | |
159 | template<typename A1, typename A2, typename A3, typename A4, typename A5, | |
160 | typename A6, typename A7, typename A8> | |
161 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, | |
162 | const A6 &a6, const A7 &a7, const A8 &a8) const | |
163 | { | |
164 | if(!_postconstructed) | |
165 | { | |
166 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
167 | a1, a2, a3, a4, a5, a6, a7, a8); | |
168 | _postconstructed = true; | |
169 | } | |
170 | return _sp; | |
171 | } | |
172 | template<typename A1, typename A2, typename A3, typename A4, typename A5, | |
173 | typename A6, typename A7, typename A8, typename A9> | |
174 | const shared_ptr<T>& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, | |
175 | const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9) const | |
176 | { | |
177 | if(!_postconstructed) | |
178 | { | |
179 | adl_postconstruct(_sp, const_cast<typename boost::remove_const<T>::type *>(_sp.get()), | |
180 | a1, a2, a3, a4, a5, a6, a7, a8, a9); | |
181 | _postconstructed = true; | |
182 | } | |
183 | return _sp; | |
184 | } | |
185 | #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
186 | private: | |
187 | friend class boost::signals2::deconstruct_access; | |
188 | postconstructor_invoker(const shared_ptr<T> & sp): | |
189 | _sp(sp), _postconstructed(false) | |
190 | {} | |
191 | shared_ptr<T> _sp; | |
192 | mutable bool _postconstructed; | |
193 | }; | |
194 | ||
195 | namespace detail | |
196 | { | |
197 | ||
198 | template< std::size_t N, std::size_t A > struct sp_aligned_storage | |
199 | { | |
200 | union type | |
201 | { | |
202 | char data_[ N ]; | |
203 | typename boost::type_with_alignment< A >::type align_; | |
204 | }; | |
205 | }; | |
206 | ||
207 | template< class T > class deconstruct_deleter | |
208 | { | |
209 | private: | |
210 | ||
211 | typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type; | |
212 | ||
213 | bool initialized_; | |
214 | storage_type storage_; | |
215 | ||
216 | private: | |
217 | ||
218 | void destroy() | |
219 | { | |
220 | if( initialized_ ) | |
221 | { | |
222 | T* p = reinterpret_cast< T* >( storage_.data_ ); | |
223 | using boost::signals2::detail::adl_predestruct; | |
224 | adl_predestruct(const_cast<typename boost::remove_const<T>::type *>(p)); | |
225 | p->~T(); | |
226 | initialized_ = false; | |
227 | } | |
228 | } | |
229 | ||
230 | public: | |
231 | ||
232 | deconstruct_deleter(): initialized_( false ) | |
233 | { | |
234 | } | |
235 | ||
236 | // this copy constructor is an optimization: we don't need to copy the storage_ member, | |
237 | // and shouldn't be copying anyways after initialized_ becomes true | |
238 | deconstruct_deleter(const deconstruct_deleter &): initialized_( false ) | |
239 | { | |
240 | } | |
241 | ||
242 | ~deconstruct_deleter() | |
243 | { | |
244 | destroy(); | |
245 | } | |
246 | ||
247 | void operator()( T * ) | |
248 | { | |
249 | destroy(); | |
250 | } | |
251 | ||
252 | void * address() | |
253 | { | |
254 | return storage_.data_; | |
255 | } | |
256 | ||
257 | void set_initialized() | |
258 | { | |
259 | initialized_ = true; | |
260 | } | |
261 | }; | |
262 | } // namespace detail | |
263 | ||
264 | class deconstruct_access | |
265 | { | |
266 | public: | |
267 | ||
268 | template< class T > | |
269 | static postconstructor_invoker<T> deconstruct() | |
270 | { | |
271 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
272 | ||
273 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
274 | ||
275 | void * pv = pd->address(); | |
276 | ||
277 | new( pv ) T(); | |
278 | pd->set_initialized(); | |
279 | ||
280 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
281 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
282 | return retval; | |
283 | ||
284 | } | |
285 | ||
286 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
287 | ||
288 | // Variadic templates, rvalue reference | |
289 | ||
290 | template< class T, class... Args > | |
291 | static postconstructor_invoker<T> deconstruct( Args && ... args ) | |
292 | { | |
293 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
294 | ||
295 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
296 | ||
297 | void * pv = pd->address(); | |
298 | ||
299 | new( pv ) T( std::forward<Args>( args )... ); | |
300 | pd->set_initialized(); | |
301 | ||
302 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
303 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
304 | return retval; | |
305 | } | |
306 | ||
307 | #else | |
308 | ||
309 | template< class T, class A1 > | |
310 | static postconstructor_invoker<T> deconstruct( A1 const & a1 ) | |
311 | { | |
312 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
313 | ||
314 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
315 | ||
316 | void * pv = pd->address(); | |
317 | ||
318 | new( pv ) T( a1 ); | |
319 | pd->set_initialized(); | |
320 | ||
321 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
322 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
323 | return retval; | |
324 | } | |
325 | ||
326 | template< class T, class A1, class A2 > | |
327 | static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 ) | |
328 | { | |
329 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
330 | ||
331 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
332 | ||
333 | void * pv = pd->address(); | |
334 | ||
335 | new( pv ) T( a1, a2 ); | |
336 | pd->set_initialized(); | |
337 | ||
338 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
339 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
340 | return retval; | |
341 | } | |
342 | ||
343 | template< class T, class A1, class A2, class A3 > | |
344 | static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 ) | |
345 | { | |
346 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
347 | ||
348 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
349 | ||
350 | void * pv = pd->address(); | |
351 | ||
352 | new( pv ) T( a1, a2, a3 ); | |
353 | pd->set_initialized(); | |
354 | ||
355 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
356 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
357 | return retval; | |
358 | } | |
359 | ||
360 | template< class T, class A1, class A2, class A3, class A4 > | |
361 | static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) | |
362 | { | |
363 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
364 | ||
365 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
366 | ||
367 | void * pv = pd->address(); | |
368 | ||
369 | new( pv ) T( a1, a2, a3, a4 ); | |
370 | pd->set_initialized(); | |
371 | ||
372 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
373 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
374 | return retval; | |
375 | } | |
376 | ||
377 | template< class T, class A1, class A2, class A3, class A4, class A5 > | |
378 | static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) | |
379 | { | |
380 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
381 | ||
382 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
383 | ||
384 | void * pv = pd->address(); | |
385 | ||
386 | new( pv ) T( a1, a2, a3, a4, a5 ); | |
387 | pd->set_initialized(); | |
388 | ||
389 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
390 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
391 | return retval; | |
392 | } | |
393 | ||
394 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > | |
395 | static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) | |
396 | { | |
397 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
398 | ||
399 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
400 | ||
401 | void * pv = pd->address(); | |
402 | ||
403 | new( pv ) T( a1, a2, a3, a4, a5, a6 ); | |
404 | pd->set_initialized(); | |
405 | ||
406 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
407 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
408 | return retval; | |
409 | } | |
410 | ||
411 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > | |
412 | static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) | |
413 | { | |
414 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
415 | ||
416 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
417 | ||
418 | void * pv = pd->address(); | |
419 | ||
420 | new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); | |
421 | pd->set_initialized(); | |
422 | ||
423 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
424 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
425 | return retval; | |
426 | } | |
427 | ||
428 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > | |
429 | static postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) | |
430 | { | |
431 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
432 | ||
433 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
434 | ||
435 | void * pv = pd->address(); | |
436 | ||
437 | new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); | |
438 | pd->set_initialized(); | |
439 | ||
440 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
441 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
442 | return retval; | |
443 | } | |
444 | ||
445 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > | |
446 | static postconstructor_invoker<T> deconstruct( 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 ) | |
447 | { | |
448 | boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); | |
449 | ||
450 | detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); | |
451 | ||
452 | void * pv = pd->address(); | |
453 | ||
454 | new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); | |
455 | pd->set_initialized(); | |
456 | ||
457 | boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); | |
458 | boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); | |
459 | return retval; | |
460 | } | |
461 | ||
462 | #endif | |
463 | }; | |
464 | ||
465 | // Zero-argument versions | |
466 | // | |
467 | // Used even when variadic templates are available because of the new T() vs new T issue | |
468 | ||
469 | template< class T > postconstructor_invoker<T> deconstruct() | |
470 | { | |
471 | return deconstruct_access::deconstruct<T>(); | |
472 | } | |
473 | ||
474 | #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) | |
475 | ||
476 | // Variadic templates, rvalue reference | |
477 | ||
478 | template< class T, class... Args > postconstructor_invoker< T > deconstruct( Args && ... args ) | |
479 | { | |
480 | return deconstruct_access::deconstruct<T>( std::forward<Args>( args )... ); | |
481 | } | |
482 | ||
483 | #else | |
484 | ||
485 | // C++03 version | |
486 | ||
487 | template< class T, class A1 > | |
488 | postconstructor_invoker<T> deconstruct( A1 const & a1 ) | |
489 | { | |
490 | return deconstruct_access::deconstruct<T>(a1); | |
491 | } | |
492 | ||
493 | template< class T, class A1, class A2 > | |
494 | postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2 ) | |
495 | { | |
496 | return deconstruct_access::deconstruct<T>(a1,a2); | |
497 | } | |
498 | ||
499 | template< class T, class A1, class A2, class A3 > | |
500 | postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 ) | |
501 | { | |
502 | return deconstruct_access::deconstruct<T>(a1,a2,a3); | |
503 | } | |
504 | ||
505 | template< class T, class A1, class A2, class A3, class A4 > | |
506 | postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) | |
507 | { | |
508 | return deconstruct_access::deconstruct<T>(a1,a2,a3,a4); | |
509 | } | |
510 | ||
511 | template< class T, class A1, class A2, class A3, class A4, class A5 > | |
512 | postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) | |
513 | { | |
514 | return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5); | |
515 | } | |
516 | ||
517 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > | |
518 | postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) | |
519 | { | |
520 | return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6); | |
521 | } | |
522 | ||
523 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > | |
524 | postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) | |
525 | { | |
526 | return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7); | |
527 | } | |
528 | ||
529 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > | |
530 | postconstructor_invoker<T> deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8 ) | |
531 | { | |
532 | return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8); | |
533 | } | |
534 | ||
535 | template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > | |
536 | postconstructor_invoker<T> deconstruct( 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 ) | |
537 | { | |
538 | return deconstruct_access::deconstruct<T>(a1,a2,a3,a4,a5,a6,a7,a8,a9); | |
539 | } | |
540 | ||
541 | #endif | |
542 | ||
543 | } // namespace signals2 | |
544 | } // namespace boost | |
545 | ||
546 | #endif // #ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP |