Chris@16: #ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP Chris@16: #define BOOST_SIGNALS2_DECONSTRUCT_HPP Chris@16: Chris@16: // deconstruct.hpp Chris@16: // Chris@16: // A factory function for creating a shared_ptr which creates Chris@16: // an object and its owning shared_ptr with one allocation, similar Chris@16: // to make_shared(). It also supports postconstructors Chris@16: // and predestructors through unqualified calls of adl_postconstruct() and Chris@16: // adl_predestruct, relying on argument-dependent Chris@16: // lookup to find the appropriate postconstructor or predestructor. Chris@16: // Passing arguments to postconstructors is also supported. Chris@16: // Chris@16: // based on make_shared.hpp and make_shared_access patch from Michael Marcin Chris@16: // Chris@16: // Copyright (c) 2007, 2008 Peter Dimov Chris@16: // Copyright (c) 2008 Michael Marcin Chris@16: // Copyright (c) 2009 Frank Mori Hess Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt Chris@16: // Chris@16: // See http://www.boost.org Chris@16: // for more information Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: template class enable_shared_from_this; Chris@16: Chris@16: namespace signals2 Chris@16: { Chris@16: class deconstruct_access; Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: inline void adl_predestruct(...) {} Chris@16: } // namespace detail Chris@16: Chris@16: template Chris@16: class postconstructor_invoker Chris@16: { Chris@16: public: Chris@16: operator const shared_ptr & () const Chris@16: { Chris@16: return postconstruct(); Chris@16: } Chris@16: const shared_ptr& postconstruct() const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get())); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: template Chris@16: const shared_ptr& postconstruct(Args && ... args) Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: std::forward(args)...); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2, a3); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2, a3, a4); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2, a3, a4, a5); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, Chris@16: const A6 &a6) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2, a3, a4, a5, a6); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, Chris@16: const A6 &a6, const A7 &a7) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2, a3, a4, a5, a6, a7); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, Chris@16: const A6 &a6, const A7 &a7, const A8 &a8) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2, a3, a4, a5, a6, a7, a8); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: template Chris@16: const shared_ptr& postconstruct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, Chris@16: const A6 &a6, const A7 &a7, const A8 &a8, const A9 &a9) const Chris@16: { Chris@16: if(!_postconstructed) Chris@16: { Chris@16: adl_postconstruct(_sp, const_cast::type *>(_sp.get()), Chris@16: a1, a2, a3, a4, a5, a6, a7, a8, a9); Chris@16: _postconstructed = true; Chris@16: } Chris@16: return _sp; Chris@16: } Chris@16: #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: private: Chris@16: friend class boost::signals2::deconstruct_access; Chris@16: postconstructor_invoker(const shared_ptr & sp): Chris@16: _sp(sp), _postconstructed(false) Chris@16: {} Chris@16: shared_ptr _sp; Chris@16: mutable bool _postconstructed; Chris@16: }; Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: template< std::size_t N, std::size_t A > struct sp_aligned_storage Chris@16: { Chris@16: union type Chris@16: { Chris@16: char data_[ N ]; Chris@16: typename boost::type_with_alignment< A >::type align_; Chris@16: }; Chris@16: }; Chris@16: Chris@16: template< class T > class deconstruct_deleter Chris@16: { Chris@16: private: Chris@16: Chris@16: typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type; Chris@16: Chris@16: bool initialized_; Chris@16: storage_type storage_; Chris@16: Chris@16: private: Chris@16: Chris@16: void destroy() Chris@16: { Chris@16: if( initialized_ ) Chris@16: { Chris@16: T* p = reinterpret_cast< T* >( storage_.data_ ); Chris@16: using boost::signals2::detail::adl_predestruct; Chris@16: adl_predestruct(const_cast::type *>(p)); Chris@16: p->~T(); Chris@16: initialized_ = false; Chris@16: } Chris@16: } Chris@16: Chris@16: public: Chris@16: Chris@16: deconstruct_deleter(): initialized_( false ) Chris@16: { Chris@16: } Chris@16: Chris@16: // this copy constructor is an optimization: we don't need to copy the storage_ member, Chris@16: // and shouldn't be copying anyways after initialized_ becomes true Chris@16: deconstruct_deleter(const deconstruct_deleter &): initialized_( false ) Chris@16: { Chris@16: } Chris@16: Chris@16: ~deconstruct_deleter() Chris@16: { Chris@16: destroy(); Chris@16: } Chris@16: Chris@16: void operator()( T * ) Chris@16: { Chris@16: destroy(); Chris@16: } Chris@16: Chris@16: void * address() Chris@16: { Chris@16: return storage_.data_; Chris@16: } Chris@16: Chris@16: void set_initialized() Chris@16: { Chris@16: initialized_ = true; Chris@16: } Chris@16: }; Chris@16: } // namespace detail Chris@16: Chris@16: class deconstruct_access Chris@16: { Chris@16: public: Chris@16: Chris@16: template< class T > Chris@16: static postconstructor_invoker deconstruct() Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T(); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: Chris@16: // Variadic templates, rvalue reference Chris@16: Chris@16: template< class T, class... Args > Chris@16: static postconstructor_invoker deconstruct( Args && ... args ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( std::forward( args )... ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: #else Chris@16: Chris@16: template< class T, class A1 > Chris@16: static postconstructor_invoker deconstruct( A1 const & a1 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2 > Chris@16: static postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3 > Chris@16: static postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2, a3 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4 > Chris@16: static postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2, a3, a4 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5 > Chris@16: static postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2, a3, a4, a5 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > Chris@16: static postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2, a3, a4, a5, a6 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > Chris@16: static postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2, a3, a4, a5, a6, a7 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > Chris@16: static postconstructor_invoker 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 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > Chris@16: static postconstructor_invoker 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 ) Chris@16: { Chris@16: boost::shared_ptr< T > pt( static_cast< T* >( 0 ), detail::deconstruct_deleter< T >() ); Chris@16: Chris@16: detail::deconstruct_deleter< T > * pd = boost::get_deleter< detail::deconstruct_deleter< T > >( pt ); Chris@16: Chris@16: void * pv = pd->address(); Chris@16: Chris@16: new( pv ) T( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); Chris@16: pd->set_initialized(); Chris@16: Chris@16: boost::shared_ptr< T > retval( pt, static_cast< T* >( pv ) ); Chris@16: boost::detail::sp_enable_shared_from_this(&retval, retval.get(), retval.get()); Chris@16: return retval; Chris@16: } Chris@16: Chris@16: #endif Chris@16: }; Chris@16: Chris@16: // Zero-argument versions Chris@16: // Chris@16: // Used even when variadic templates are available because of the new T() vs new T issue Chris@16: Chris@16: template< class T > postconstructor_invoker deconstruct() Chris@16: { Chris@16: return deconstruct_access::deconstruct(); Chris@16: } Chris@16: Chris@16: #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) Chris@16: Chris@16: // Variadic templates, rvalue reference Chris@16: Chris@16: template< class T, class... Args > postconstructor_invoker< T > deconstruct( Args && ... args ) Chris@16: { Chris@16: return deconstruct_access::deconstruct( std::forward( args )... ); Chris@16: } Chris@16: Chris@16: #else Chris@16: Chris@16: // C++03 version Chris@16: Chris@16: template< class T, class A1 > Chris@16: postconstructor_invoker deconstruct( A1 const & a1 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2 > Chris@16: postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3 > Chris@16: postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2,a3); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4 > Chris@16: postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2,a3,a4); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5 > Chris@16: postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2,a3,a4,a5); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6 > Chris@16: postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2,a3,a4,a5,a6); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 > Chris@16: postconstructor_invoker deconstruct( A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2,a3,a4,a5,a6,a7); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > Chris@16: postconstructor_invoker 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 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2,a3,a4,a5,a6,a7,a8); Chris@16: } Chris@16: Chris@16: template< class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > Chris@16: postconstructor_invoker 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 ) Chris@16: { Chris@16: return deconstruct_access::deconstruct(a1,a2,a3,a4,a5,a6,a7,a8,a9); Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: } // namespace signals2 Chris@16: } // namespace boost Chris@16: Chris@16: #endif // #ifndef BOOST_SIGNALS2_DECONSTRUCT_HPP