Make shared_from_raw and weak_from_raw return consistent values in a constructor, regardless of order, as suggested by Gavin Lambert in #8.

This commit is contained in:
Peter Dimov
2015-01-22 20:47:01 +02:00
parent 75de3dbcf1
commit 3fd53ced83
5 changed files with 139 additions and 5 deletions

View File

@@ -53,7 +53,7 @@ protected:
private:
void init_weak_once() const
void init_if_expired() const
{
if( weak_this_.expired() )
{
@@ -62,6 +62,15 @@ private:
}
}
void init_if_empty() const
{
if( weak_this_._empty() )
{
shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
weak_this_ = shared_this_;
}
}
#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public:
#else
@@ -74,7 +83,7 @@ private:
shared_ptr<void const volatile> shared_from_this() const
{
init_weak_once();
init_if_expired();
return shared_ptr<void const volatile>( weak_this_ );
}
@@ -83,6 +92,17 @@ private:
return const_cast< enable_shared_from_raw const * >( this )->shared_from_this();
}
weak_ptr<void const volatile> weak_from_this() const
{
init_if_empty();
return weak_this_;
}
weak_ptr<void const volatile> weak_from_this() const volatile
{
return const_cast< enable_shared_from_raw const * >( this )->weak_from_this();
}
// Note: invoked automatically by shared_ptr; do not call
template<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
{
@@ -125,7 +145,7 @@ boost::weak_ptr<T> weak_from_raw(T *p)
{
BOOST_ASSERT(p != 0);
boost::weak_ptr<T> result;
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_this_, p);
result._internal_aliasing_assign(p->enable_shared_from_raw::weak_from_this(), p);
return result;
}