#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED #define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED // // enable_shared_from_this.hpp // // Copyright (c) 2002 Peter Dimov // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html // #include #include #include #include namespace boost { class enable_shared_from_this; template< class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); template< class Y > void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); template< class T > shared_ptr shared_from_this( T * p ); class enable_shared_from_this { protected: enable_shared_from_this() { } enable_shared_from_this(enable_shared_from_this const &) { } enable_shared_from_this & operator=(enable_shared_from_this const &) { return *this; } ~enable_shared_from_this() { BOOST_ASSERT( _shared_ptr.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist } private: mutable weak_ptr _weak_ptr; mutable shared_ptr _shared_ptr; template void init_weak_once( T * p ) const { if( !_weak_ptr ) { _shared_ptr.reset( p, detail::sp_deleter_wrapper() ); _weak_ptr = _shared_ptr; } } template void sp_accept_owner( shared_ptr & owner ) const { if( _weak_ptr.use_count() == 0 ) { _weak_ptr = owner; }else if( _shared_ptr ) { BOOST_ASSERT( owner.unique() ); // no weak_ptrs to owner should exist either, but there's no way to check that detail::sp_deleter_wrapper * pd = get_deleter( _shared_ptr ); BOOST_ASSERT( pd != 0 ); pd->set_deleter( owner ); owner.reset( _shared_ptr, owner.get() ); _shared_ptr.reset(); } } template< class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ); template< class Y > friend void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ); }; template< class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe ) { if( pe != 0 ) { pe->sp_accept_owner( *ptr ); } } template< class Y > inline void sp_accept_owner( shared_ptr * ptr, enable_shared_from_this const * pe, void * /*pd*/ ) { if( pe != 0 ) { pe->sp_accept_owner( *ptr ); } } template< class T > inline shared_ptr shared_from_this( T * p ) { p->enable_shared_from_this::init_weak_once( p ); return shared_ptr( shared_ptr(_weak_ptr), p ); } } // namespace boost #endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED