Index: boost/enable_shared_from_this.hpp =================================================================== --- boost/enable_shared_from_this.hpp (revision 44152) +++ boost/enable_shared_from_this.hpp (working copy) @@ -109,6 +109,15 @@ } }; +// register enable_shared_from_this as an observer +template void sp_notify_observer( shared_ptr * ptr, enable_shared_from_this const * pe ) +{ + if(pe != 0) + { + pe->_internal_accept_owner(*ptr); + } +} + } // namespace boost #endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED Index: boost/shared_ptr.hpp =================================================================== --- boost/shared_ptr.hpp (revision 44152) +++ boost/shared_ptr.hpp (working copy) @@ -50,7 +50,6 @@ template class shared_ptr; template class weak_ptr; -template class enable_shared_from_this; namespace detail { @@ -93,14 +92,6 @@ struct ignore_enable_shared_from_this_tag {}; -template void sp_enable_shared_from_this( boost::shared_ptr * ptr, boost::enable_shared_from_this const * pe ) -{ - if(pe != 0) - { - pe->_internal_accept_owner(*ptr); - } -} - #ifdef _MANAGED // Avoid C4793, ... causes native code generation @@ -110,18 +101,18 @@ template sp_any_pointer( T* ) {} }; -inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer ) +inline void sp_notify_observer( sp_any_pointer, sp_any_pointer ) { } #else // _MANAGED #ifdef sgi -// Turn off: the last argument of the varargs function "sp_enable_shared_from_this" is unnamed +// Turn off: the last argument of the varargs function "sp_notify_observer" is unnamed # pragma set woff 3506 #endif -inline void sp_enable_shared_from_this( ... ) +inline void sp_notify_observer( ... ) { } @@ -178,7 +169,8 @@ template explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete { - boost::detail::sp_enable_shared_from_this( this, p ); + using detail::sp_notify_observer; + sp_notify_observer( this, p ); } // @@ -189,14 +181,16 @@ template shared_ptr(Y * p, D d): px(p), pn(p, d) { - boost::detail::sp_enable_shared_from_this( this, p ); + using detail::sp_notify_observer; + sp_notify_observer( this, p ); } // As above, but with allocator. A's copy constructor shall not throw. template shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a ) { - boost::detail::sp_enable_shared_from_this( this, p ); + using detail::sp_notify_observer; + sp_notify_observer( this, p ); } // generated copy constructor, assignment, destructor are fine... @@ -221,6 +215,13 @@ } template + explicit shared_ptr(detail::weak_count const & wc, Y * p): pn(wc) // may throw + { + // it is now safe to copy p, as pn(wc) did not throw + px = p; + } + + template shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws { } @@ -272,7 +273,8 @@ { Y * tmp = r.get(); pn = boost::detail::shared_count(r); - boost::detail::sp_enable_shared_from_this( this, tmp ); + using detail::sp_notify_observer; + sp_notify_observer( this, tmp ); } #if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) @@ -282,7 +284,8 @@ { typename Ap::element_type * tmp = r.get(); pn = boost::detail::shared_count( r ); - boost::detail::sp_enable_shared_from_this( this, tmp ); + using detail::sp_notify_observer; + sp_notify_observer( this, tmp ); } @@ -478,6 +481,11 @@ return pn.get_deleter( ti ); } + detail::shared_count const & _internal_shared_count() const + { + return pn; + } + // Tasteless as this may seem, making all members public allows member templates // to work in the absence of member template friends. (Matthew Langston) Index: boost/enable_shared_from_this_light.hpp =================================================================== --- boost/enable_shared_from_this_light.hpp (revision 0) +++ boost/enable_shared_from_this_light.hpp (revision 0) @@ -0,0 +1,69 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_THIS_LIGHT_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_THIS_LIGHT_HPP_INCLUDED + +// +// enable_shared_from_this_light.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_light.html +// + +#include +#include + +namespace boost +{ + +template class enable_shared_from_this_light +{ +protected: + + enable_shared_from_this_light() + { + } + + enable_shared_from_this_light(enable_shared_from_this_light const &) + { + } + + enable_shared_from_this_light & operator=(enable_shared_from_this_light const &) + { + return *this; + } + + ~enable_shared_from_this_light() + { + } + +public: + + shared_ptr shared_from_this() + { + return shared_ptr(_internal_weak_count,static_cast(this)); + } + + shared_ptr shared_from_this() const + { + return shared_ptr(_internal_weak_count,static_cast(this)); + } + + mutable detail::weak_count _internal_weak_count; +}; + +// register enable_shared_from_this_light as an observer +template void sp_notify_observer( shared_ptr * ptr, enable_shared_from_this_light const * pe ) +{ + if(pe != 0) + { + pe->_internal_weak_count = ptr->_internal_shared_count(); + } +} + +} // namespace boost + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_LIGHT_HPP_INCLUDED