diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp index 2745649..e1ca96a 100644 --- a/include/boost/detail/shared_count.hpp +++ b/include/boost/detail/shared_count.hpp @@ -220,6 +220,18 @@ public: if( pi_ != 0 ) pi_->add_ref_copy(); } +#if defined( BOOST_HAS_RVALUE_REFS ) + + shared_count(shared_count && r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + r.pi_ = 0; + } + +#endif + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0 diff --git a/include/boost/enable_shared_from_this.hpp b/include/boost/enable_shared_from_this.hpp index f474714..65ddf87 100644 --- a/include/boost/enable_shared_from_this.hpp +++ b/include/boost/enable_shared_from_this.hpp @@ -13,7 +13,7 @@ // http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html // -#include +#include #include #include #include @@ -32,7 +32,7 @@ template class enable_shared_from_this T * p = dynamic_cast(const_cast(this)); _internal_shared_this = shared_ptr( p, detail::sp_deleter_wrapper() ); BOOST_ASSERT(_internal_shared_this.get() == this); - _internal_weak_this = _internal_shared_this; + _internal_weak_count = _internal_shared_this.get_shared_count(); } } @@ -43,7 +43,7 @@ template class enable_shared_from_this typedef T _internal_element_type; // for bcc 5.5.1 mutable shared_ptr<_internal_element_type> _internal_shared_this; - mutable weak_ptr<_internal_element_type> _internal_weak_this; + mutable detail::weak_count _internal_weak_count; mutable bool _owned; protected: @@ -77,17 +77,15 @@ public: shared_ptr shared_from_this() { init_internal_shared_once(); - shared_ptr p(_internal_weak_this); - BOOST_ASSERT(p.get() == this); - return p; + T * p = dynamic_cast(this); + return shared_ptr( detail::shared_count( _internal_weak_count ), p ); } shared_ptr shared_from_this() const { init_internal_shared_once(); - shared_ptr p(_internal_weak_this); - BOOST_ASSERT(p.get() == this); - return p; + T const * p = dynamic_cast(this); + return shared_ptr( detail::shared_count( _internal_weak_count ), p ); } template @@ -97,8 +95,7 @@ public: { if( !_internal_shared_this ) { - T * p = dynamic_cast(const_cast(this)); - _internal_weak_this = shared_ptr(owner, p); + _internal_weak_count = owner.get_shared_count(); }else { BOOST_ASSERT(owner.unique()); // no weak_ptrs to owner should exist either, but there's no way to check that diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index 5697339..88fab8f 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -228,6 +228,11 @@ public: { } + template + shared_ptr(detail::shared_count const & c, Y * p): px(p), pn(c) // never throws + { + } + // aliasing template< class Y > shared_ptr( shared_ptr const & r, T * p ): px( p ), pn( r.pn ) // never throws @@ -341,6 +346,11 @@ public: r.px = 0; } + template + shared_ptr(detail::shared_count && c, Y * p): px(p), pn( static_cast< detail::shared_count && >( c ) ) // never throws + { + } + shared_ptr & operator=( shared_ptr && r ) // never throws { this_type( static_cast< shared_ptr && >( r ) ).swap( *this ); @@ -467,6 +477,11 @@ public: pn.swap(other.pn); } + detail::shared_count const & get_shared_count() const // never throws + { + return pn; + } + template bool _internal_less(shared_ptr const & rhs) const { return pn < rhs.pn;