• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
adl_predestruct(...)45   inline void adl_predestruct(...) {}
46 } // namespace detail
47 
48 template<typename T>
49     class postconstructor_invoker
50 {
51 public:
operator const shared_ptr<T>&() const52     operator const shared_ptr<T> & () const
53     {
54         return postconstruct();
55     }
postconstruct() const56     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>
postconstruct(Args &&...args) const67       const shared_ptr<T>& postconstruct(Args && ... args) const
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>
postconstruct(const A1 & a1) const79       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>
postconstruct(const A1 & a1,const A2 & a2) const90       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>
postconstruct(const A1 & a1,const A2 & a2,const A3 & a3) const101       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>
postconstruct(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4) const112       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>
postconstruct(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5) const123       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>
postconstruct(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6) const135       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>
postconstruct(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7) const148       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>
postconstruct(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8) const161       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>
postconstruct(const A1 & a1,const A2 & a2,const A3 & a3,const A4 & a4,const A5 & a5,const A6 & a6,const A7 & a7,const A8 & a8,const A9 & a9) const174       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;
postconstructor_invoker(const shared_ptr<T> & sp)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 
destroy()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 
deconstruct_deleter()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
deconstruct_deleter(const deconstruct_deleter &)238     deconstruct_deleter(const deconstruct_deleter &): initialized_( false )
239     {
240     }
241 
~deconstruct_deleter()242     ~deconstruct_deleter()
243     {
244         destroy();
245     }
246 
operator ()(T *)247     void operator()( T * )
248     {
249         destroy();
250     }
251 
address()252     void * address()
253     {
254         return storage_.data_;
255     }
256 
set_initialized()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 >
deconstruct()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 >
deconstruct(Args &&...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 >
deconstruct(A1 const & 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 >
deconstruct(A1 const & a1,A2 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & a4,A5 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & a4,A5 const & a5,A6 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & a4,A5 const & a5,A6 const & a6,A7 const & 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 >
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)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 >
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)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 
deconstruct()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 
deconstruct(Args &&...args)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 >
deconstruct(A1 const & 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 >
deconstruct(A1 const & a1,A2 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & a4,A5 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & a4,A5 const & a5,A6 const & 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 >
deconstruct(A1 const & a1,A2 const & a2,A3 const & a3,A4 const & a4,A5 const & a5,A6 const & a6,A7 const & 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 >
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)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 >
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)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
547