Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r57197 - in trunk: boost/smart_ptr libs/smart_ptr/test
From: fmhess_at_[hidden]
Date: 2009-10-28 15:10:47


Author: fmhess
Date: 2009-10-28 15:10:47 EDT (Wed, 28 Oct 2009)
New Revision: 57197
URL: http://svn.boost.org/trac/boost/changeset/57197

Log:
Renamed enable_shared_from_this2 to enable_shared_from_raw and
added shared_from_raw free function. These changes fix the pointer
value in shared_ptr which were obtained before an external shared_ptr has
taken ownership of the object (for example when a shared_ptr to
this is obtained in an object's constructor).

Added:
   trunk/boost/smart_ptr/enable_shared_from_raw.hpp (contents, props changed)
      - copied, changed from r57191, /trunk/boost/smart_ptr/enable_shared_from_this2.hpp
Removed:
   trunk/boost/smart_ptr/enable_shared_from_this2.hpp
Text files modified:
   trunk/boost/smart_ptr/enable_shared_from_raw.hpp | 85 +++++++++++++++++++++++++--------------
   trunk/boost/smart_ptr/shared_ptr.hpp | 10 ---
   trunk/libs/smart_ptr/test/esft_constructor_test.cpp | 26 +++++------
   3 files changed, 69 insertions(+), 52 deletions(-)

Copied: trunk/boost/smart_ptr/enable_shared_from_raw.hpp (from r57191, /trunk/boost/smart_ptr/enable_shared_from_this2.hpp)
==============================================================================
--- /trunk/boost/smart_ptr/enable_shared_from_this2.hpp (original)
+++ trunk/boost/smart_ptr/enable_shared_from_raw.hpp 2009-10-28 15:10:47 EDT (Wed, 28 Oct 2009)
@@ -1,11 +1,11 @@
-#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
-#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
+#ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
+#define BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED
 
 //
-// enable_shared_from_this2.hpp
+// enable_shared_from_raw.hpp
 //
 // Copyright 2002, 2009 Peter Dimov
-// Copyright 2008 Frank Mori Hess
+// 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
@@ -14,14 +14,17 @@
 
 #include <boost/config.hpp>
 #include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
 #include <boost/assert.hpp>
 #include <boost/detail/workaround.hpp>
 
 namespace boost
 {
+template<typename T> boost::shared_ptr<T> shared_from_raw(T *);
 
 namespace detail
 {
+template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
 
 class esft2_deleter_wrapper
 {
@@ -49,68 +52,73 @@
 
 } // namespace detail
 
-template< class T > class enable_shared_from_this2
+class enable_shared_from_raw
 {
 protected:
 
- enable_shared_from_this2()
+ enable_shared_from_raw()
     {
     }
 
- enable_shared_from_this2( enable_shared_from_this2 const & )
+ enable_shared_from_raw( enable_shared_from_raw const & )
     {
     }
 
- enable_shared_from_this2 & operator=( enable_shared_from_this2 const & )
+ enable_shared_from_raw & operator=( enable_shared_from_raw const & )
     {
         return *this;
     }
 
- ~enable_shared_from_this2()
+ ~enable_shared_from_raw()
     {
         BOOST_ASSERT( shared_this_.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
     }
 
 private:
 
- mutable weak_ptr<T> weak_this_;
- mutable shared_ptr<T> shared_this_;
+ mutable weak_ptr<void> weak_this_;
+ mutable shared_ptr<void> shared_this_;
 
-public:
+private:
 
- shared_ptr<T> shared_from_this()
+ void init_weak_once() const
     {
- init_weak_once();
- return shared_ptr<T>( weak_this_ );
+ if( weak_this_.expired() )
+ {
+ shared_this_.reset( static_cast<void*>(0), detail::esft2_deleter_wrapper() );
+ weak_this_ = shared_this_;
+ }
     }
 
- shared_ptr<T const> shared_from_this() const
+#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+public:
+#else
+private:
+ template<class Y> friend class shared_ptr;
+ template<typename T> friend boost::shared_ptr<T> shared_from_raw(T *);
+ template< class X, class Y > friend inline void detail::sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
+#endif
+
+ shared_ptr<void> shared_from_this()
     {
         init_weak_once();
- return shared_ptr<T>( weak_this_ );
+ return shared_ptr<void>( weak_this_ );
     }
 
-private:
-
- void init_weak_once() const
+ shared_ptr<const void> shared_from_this() const
     {
- if( weak_this_._empty() )
- {
- shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() );
- weak_this_ = shared_this_;
- }
+ init_weak_once();
+ return shared_ptr<const void>( weak_this_ );
     }
 
-public: // actually private, but avoids compiler template friendship issues
-
     // 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
     {
         BOOST_ASSERT( ppx != 0 );
 
- if( weak_this_.use_count() == 0 )
+ if( weak_this_.expired() )
         {
- weak_this_ = shared_ptr<T>( *ppx, py );
+ weak_this_ = *ppx;
         }
         else if( shared_this_.use_count() != 0 )
         {
@@ -127,6 +135,23 @@
     }
 };
 
+template<typename T>
+boost::shared_ptr<T> shared_from_raw(T *p)
+{
+ return boost::shared_ptr<T>(p->enable_shared_from_raw::shared_from_this(), p);
+}
+
+namespace detail
+{
+ template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * 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_THIS2_HPP_INCLUDED
+#endif // #ifndef BOOST_ENABLE_SHARED_FROM_RAW_HPP_INCLUDED

Deleted: trunk/boost/smart_ptr/enable_shared_from_this2.hpp
==============================================================================
--- trunk/boost/smart_ptr/enable_shared_from_this2.hpp 2009-10-28 15:10:47 EDT (Wed, 28 Oct 2009)
+++ (empty file)
@@ -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 <boost/config.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/assert.hpp>
-#include <boost/detail/workaround.hpp>
-
-namespace boost
-{
-
-namespace detail
-{
-
-class esft2_deleter_wrapper
-{
-private:
-
- shared_ptr<void> deleter_;
-
-public:
-
- esft2_deleter_wrapper()
- {
- }
-
- template< class T > void set_deleter( shared_ptr<T> 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<T> weak_this_;
- mutable shared_ptr<T> shared_this_;
-
-public:
-
- shared_ptr<T> shared_from_this()
- {
- init_weak_once();
- return shared_ptr<T>( weak_this_ );
- }
-
- shared_ptr<T const> shared_from_this() const
- {
- init_weak_once();
- return shared_ptr<T>( 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<class X, class Y> void _internal_accept_owner( shared_ptr<X> * ppx, Y * py ) const
- {
- BOOST_ASSERT( ppx != 0 );
-
- if( weak_this_.use_count() == 0 )
- {
- weak_this_ = shared_ptr<T>( *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<detail::esft2_deleter_wrapper>( 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

Modified: trunk/boost/smart_ptr/shared_ptr.hpp
==============================================================================
--- trunk/boost/smart_ptr/shared_ptr.hpp (original)
+++ trunk/boost/smart_ptr/shared_ptr.hpp 2009-10-28 15:10:47 EDT (Wed, 28 Oct 2009)
@@ -61,7 +61,7 @@
 template<class T> class shared_ptr;
 template<class T> class weak_ptr;
 template<class T> class enable_shared_from_this;
-template<class T> class enable_shared_from_this2;
+class enable_shared_from_raw;
 
 namespace detail
 {
@@ -110,13 +110,7 @@
     }
 }
 
-template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * 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<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
 
 #ifdef _MANAGED
 

Modified: trunk/libs/smart_ptr/test/esft_constructor_test.cpp
==============================================================================
--- trunk/libs/smart_ptr/test/esft_constructor_test.cpp (original)
+++ trunk/libs/smart_ptr/test/esft_constructor_test.cpp 2009-10-28 15:10:47 EDT (Wed, 28 Oct 2009)
@@ -13,14 +13,13 @@
 // See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 //
-
-#include <boost/smart_ptr/enable_shared_from_this2.hpp>
+#include <boost/smart_ptr/enable_shared_from_raw.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 #include <boost/detail/lightweight_test.hpp>
 #include <memory>
 
-class X: public boost::enable_shared_from_this2< X >
+class X: public boost::enable_shared_from_raw
 {
 private:
 
@@ -42,7 +41,7 @@
     explicit X( int expected, boost::shared_ptr<X> *early_px = 0 ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
     {
         ++instances;
- if( early_px ) *early_px = shared_from_this();
+ if( early_px ) *early_px = shared_from_raw(this);
     }
 
     ~X()
@@ -75,7 +74,7 @@
     return !(a < b) && !(b < a);
 }
 
-struct Y: public boost::enable_shared_from_this2<Y>
+struct Y: public boost::enable_shared_from_raw
 {};
 
 int main()
@@ -87,6 +86,7 @@
         X* x = new X( 1, &early_px );
         BOOST_TEST( early_px.use_count() > 0 );
         BOOST_TEST( boost::get_deleter<X::deleter_type>(early_px) == 0 );
+ BOOST_TEST( early_px.get() == x );
         boost::shared_ptr<X> px( x, &X::deleter2 );
         BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 );
         BOOST_TEST(are_shared_owners(early_px, px));
@@ -117,7 +117,7 @@
 
     {
         boost::shared_ptr<X> early_px;
- X x( 1, &early_px );
+ X x( 2, &early_px );
         BOOST_TEST( early_px.use_count() > 0 );
         boost::shared_ptr<X> px( &x, &X::deleter );
         BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 );
@@ -125,13 +125,11 @@
         BOOST_TEST( px.use_count() == 1 );
         BOOST_TEST( X::instances == 1 );
         px.reset();
- try
- {
- x.shared_from_this();
- BOOST_ERROR("x did not throw bad_weak_ptr");
- }
- catch( const boost::bad_weak_ptr & )
- {}
+ // test reinitialization after all shared_ptr have expired
+ early_px = shared_from_raw(&x);
+ px.reset( &x, &X::deleter );
+ BOOST_TEST(are_shared_owners(early_px, px));
+ early_px.reset();
     }
 
     BOOST_TEST( X::instances == 0 );
@@ -157,7 +155,7 @@
         px.reset();
         try
         {
- y.shared_from_this();
+ shared_from_raw(&y);
         }
         catch( const boost::bad_weak_ptr & )
         {


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk