diff --git a/include/boost/smart_ptr/enable_shared_from_raw.hpp b/include/boost/smart_ptr/enable_shared_from_raw.hpp new file mode 100644 index 0000000..f659c04 --- /dev/null +++ b/include/boost/smart_ptr/enable_shared_from_raw.hpp @@ -0,0 +1,144 @@ +#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED +#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED + +// +// enable_shared_from_raw.hpp +// +// Copyright 2002, 2009 Peter Dimov +// Copyright 2008-2009 Frank Mori Hess +// +// 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 +// + +#include +#include +#include +#include +#include + +namespace boost +{ +template boost::shared_ptr shared_from_raw(T *); +template boost::weak_ptr weak_from_raw(T *); + +namespace detail +{ +template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); + +} // namespace detail + +class enable_shared_from_raw +{ +protected: + + enable_shared_from_raw() + { + } + + enable_shared_from_raw( enable_shared_from_raw const & ) + { + } + + enable_shared_from_raw & operator=( enable_shared_from_raw const & ) + { + return *this; + } + + ~enable_shared_from_raw() + { + BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist + } + +private: + + void init_weak_once() const + { + if( weak_this_.expired() ) + { + shared_this_.reset( static_cast(0), detail::esft2_deleter_wrapper() ); + weak_this_ = shared_this_; + } + } + +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +private: + template friend class shared_ptr; + template friend boost::shared_ptr shared_from_raw(T *); + template friend boost::weak_ptr weak_from_raw(T *); + template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); +#endif + + shared_ptr shared_from_this() + { + init_weak_once(); + return shared_ptr( weak_this_ ); + } + + shared_ptr shared_from_this() const + { + init_weak_once(); + return shared_ptr( weak_this_ ); + } + + // Note: invoked automatically by shared_ptr; do not call + template void _internal_accept_owner( shared_ptr * ppx, Y * py ) const + { + BOOST_ASSERT( ppx != 0 ); + + if( weak_this_.expired() ) + { + weak_this_ = *ppx; + } + else if( shared_this_.use_count() != 0 ) + { + BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that + + detail::esft2_deleter_wrapper * pd = boost::get_deleter( shared_this_ ); + BOOST_ASSERT( pd != 0 ); + + pd->set_deleter( *ppx ); + + ppx->reset( shared_this_, ppx->get() ); + shared_this_.reset(); + } + } + + mutable weak_ptr weak_this_; +private: + mutable shared_ptr shared_this_; +}; + +template +boost::shared_ptr shared_from_raw(T *p) +{ + BOOST_ASSERT(p != 0); + return boost::shared_ptr(p->enable_shared_from_raw::shared_from_this(), p); +} + +template +boost::weak_ptr weak_from_raw(T *p) +{ + BOOST_ASSERT(p != 0); + boost::weak_ptr result; + result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p); + return result; +} + +namespace detail +{ + template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ) + { + if( pe != 0 ) + { + pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); + } + } +} // namepsace detail + +} // namespace boost + +#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED diff --git a/include/boost/smart_ptr/enable_shared_from_this2.hpp b/include/boost/smart_ptr/enable_shared_from_this2.hpp deleted file mode 100644 index a5bfcff..0000000 --- a/include/boost/smart_ptr/enable_shared_from_this2.hpp +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED -#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED - -// -// enable_shared_from_this2.hpp -// -// Copyright 2002, 2009 Peter Dimov -// Copyright 2008 Frank Mori Hess -// -// 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 -// - -#include -#include -#include -#include - -namespace boost -{ - -namespace detail -{ - -class esft2_deleter_wrapper -{ -private: - - shared_ptr deleter_; - -public: - - esft2_deleter_wrapper() - { - } - - template< class T > void set_deleter( shared_ptr const & deleter ) - { - deleter_ = deleter; - } - - template< class T> void operator()( T* ) - { - BOOST_ASSERT( deleter_.use_count() <= 1 ); - deleter_.reset(); - } -}; - -} // namespace detail - -template< class T > class enable_shared_from_this2 -{ -protected: - - enable_shared_from_this2() - { - } - - enable_shared_from_this2( enable_shared_from_this2 const & ) - { - } - - enable_shared_from_this2 & operator=( enable_shared_from_this2 const & ) - { - return *this; - } - - ~enable_shared_from_this2() - { - BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist - } - -private: - - mutable weak_ptr weak_this_; - mutable shared_ptr shared_this_; - -public: - - shared_ptr shared_from_this() - { - init_weak_once(); - return shared_ptr( weak_this_ ); - } - - shared_ptr shared_from_this() const - { - init_weak_once(); - return shared_ptr( weak_this_ ); - } - -private: - - void init_weak_once() const - { - if( weak_this_._empty() ) - { - shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() ); - weak_this_ = shared_this_; - } - } - -public: // actually private, but avoids compiler template friendship issues - - // Note: invoked automatically by shared_ptr; do not call - template void _internal_accept_owner( shared_ptr * ppx, Y * py ) const - { - BOOST_ASSERT( ppx != 0 ); - - if( weak_this_.use_count() == 0 ) - { - weak_this_ = shared_ptr( *ppx, py ); - } - else if( shared_this_.use_count() != 0 ) - { - BOOST_ASSERT( ppx->unique() ); // no weak_ptrs should exist either, but there's no way to check that - - detail::esft2_deleter_wrapper * pd = boost::get_deleter( shared_this_ ); - BOOST_ASSERT( pd != 0 ); - - pd->set_deleter( *ppx ); - - ppx->reset( shared_this_, ppx->get() ); - shared_this_.reset(); - } - } -}; - -} // namespace boost - -#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED diff --git a/include/boost/smart_ptr/shared_ptr.hpp b/include/boost/smart_ptr/shared_ptr.hpp index 12f42c5..08cf3fe 100644 --- a/include/boost/smart_ptr/shared_ptr.hpp +++ b/include/boost/smart_ptr/shared_ptr.hpp @@ -57,7 +57,7 @@ namespace boost template class shared_ptr; template class weak_ptr; template class enable_shared_from_this; -template class enable_shared_from_this2; +class enable_shared_from_raw; namespace detail { @@ -106,13 +106,7 @@ template< class X, class Y, class T > inline void sp_enable_shared_from_this( bo } } -template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_this2< T > const * pe ) -{ - if( pe != 0 ) - { - pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) ); - } -} +template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr * ppx, Y const * py, boost::enable_shared_from_raw const * pe ); #ifdef _MANAGED @@ -612,6 +606,9 @@ template std::basic_ostream & operator<< (std:: // get_deleter +namespace detail +{ + #if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \ ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \ ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) ) @@ -619,7 +616,7 @@ template std::basic_ostream & operator<< (std:: // g++ 2.9x doesn't allow static_cast(void *) // apparently EDG 2.38 and HP aCC A.03.35 also don't accept it -template D * get_deleter(shared_ptr const & p) +template D * basic_get_deleter(shared_ptr const & p) { void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D)); return const_cast(static_cast(q)); @@ -627,13 +624,55 @@ template D * get_deleter(shared_ptr const & p) #else -template D * get_deleter(shared_ptr const & p) +template D * basic_get_deleter(shared_ptr const & p) { return static_cast(p._internal_get_deleter(BOOST_SP_TYPEID(D))); } #endif +class esft2_deleter_wrapper +{ +private: + + shared_ptr deleter_; + +public: + + esft2_deleter_wrapper() + { + } + + template< class T > void set_deleter( shared_ptr const & deleter ) + { + deleter_ = deleter; + } + template D* get_deleter() const + { + return boost::detail::basic_get_deleter(deleter_); + } + template< class T> void operator()( T* ) + { + BOOST_ASSERT( deleter_.use_count() <= 1 ); + deleter_.reset(); + } +}; + +} // namespace detail + +template D * get_deleter(shared_ptr const & p) +{ + D *del = detail::basic_get_deleter(p); + if(del == 0) + { + detail::esft2_deleter_wrapper *del_wrapper = detail::basic_get_deleter(p); +// The following get_deleter method call is fully qualified because +// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter() + if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter(); + } + return del; +} + // atomic access #if !defined(BOOST_SP_NO_ATOMIC_ACCESS) diff --git a/include/boost/smart_ptr/weak_ptr.hpp b/include/boost/smart_ptr/weak_ptr.hpp index 2e35583..5391910 100644 --- a/include/boost/smart_ptr/weak_ptr.hpp +++ b/include/boost/smart_ptr/weak_ptr.hpp @@ -194,10 +194,11 @@ public: pn.swap(other.pn); } - void _internal_assign(T * px2, boost::detail::shared_count const & pn2) + template + void _internal_aliasing_assign(weak_ptr const & r, T * px2) { px = px2; - pn = pn2; + pn = r.pn; } template bool owner_before( weak_ptr const & rhs ) const