Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r51912 - in trunk: boost/smart_ptr libs/smart_ptr/test
From: pdimov_at_[hidden]
Date: 2009-03-22 17:11:18


Author: pdimov
Date: 2009-03-22 17:11:17 EDT (Sun, 22 Mar 2009)
New Revision: 51912
URL: http://svn.boost.org/trac/boost/changeset/51912

Log:
Bring back the constructor-enabled enable_shared_from_this as enable_shared_from_this2.
Added:
   trunk/libs/smart_ptr/test/esft_constructor_test.cpp
      - copied, changed from r51580, /trunk/libs/smart_ptr/test/esft_constructor_test.cpp
Text files modified:
   trunk/boost/smart_ptr/enable_shared_from_this2.hpp | 134 +++++++++++++++++++--------------------
   trunk/boost/smart_ptr/shared_ptr.hpp | 9 ++
   trunk/boost/smart_ptr/weak_ptr.hpp | 5 +
   trunk/libs/smart_ptr/test/Jamfile.v2 | 1
   trunk/libs/smart_ptr/test/esft_constructor_test.cpp | 14 ++--
   5 files changed, 88 insertions(+), 75 deletions(-)

Modified: 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_this2.hpp 2009-03-22 17:11:17 EDT (Sun, 22 Mar 2009)
@@ -1,16 +1,15 @@
-#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
-#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+#ifndef BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
+#define BOOST_ENABLE_SHARED_FROM_THIS2_HPP_INCLUDED
 
 //
-// enable_shared_from_this.hpp
+// enable_shared_from_this2.hpp
 //
-// Copyright (c) 2002 Peter Dimov
+// 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)
-//
-// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
+// 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>
@@ -21,114 +20,113 @@
 namespace boost
 {
 
-#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
+namespace detail
+{
+
+class esft2_deleter_wrapper
+{
+private:
+
+ shared_ptr<void> deleter_;
 
-template< class T > class enable_shared_from_this;
-template< class T, class Y > void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe );
-template< class T, class Y > void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe, void * /*pd*/ );
+public:
 
-#endif
+ esft2_deleter_wrapper()
+ {
+ }
 
-template< class T > class enable_shared_from_this
+ 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_this()
+ enable_shared_from_this2()
     {
     }
 
- enable_shared_from_this(enable_shared_from_this const &)
+ enable_shared_from_this2( enable_shared_from_this2 const & )
     {
     }
 
- enable_shared_from_this & operator=(enable_shared_from_this const &)
+ enable_shared_from_this2 & operator=( enable_shared_from_this2 const & )
     {
         return *this;
     }
 
-// virtual destructor because we need a vtable for dynamic_cast from base to derived to work
- virtual ~enable_shared_from_this()
+ ~enable_shared_from_this2()
     {
- BOOST_ASSERT( _shared_count.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
+ 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();
- T * p = dynamic_cast<T *>( this );
- return shared_ptr<T>( detail::shared_count( _weak_count ), p );
+ return shared_ptr<T>( weak_this_ );
     }
 
     shared_ptr<T const> shared_from_this() const
     {
         init_weak_once();
- T const * p = dynamic_cast<T const *>( this );
- return shared_ptr<T const>( detail::shared_count( _weak_count ), p );
+ return shared_ptr<T>( weak_this_ );
     }
 
 private:
 
- mutable detail::weak_count _weak_count;
- mutable detail::shared_count _shared_count;
-
     void init_weak_once() const
     {
- if( _weak_count.empty() )
+ if( weak_this_._empty() )
         {
- detail::shared_count( (void*)0, detail::sp_deleter_wrapper() ).swap( _shared_count );
- _weak_count = _shared_count;
+ shared_this_.reset( static_cast< T* >( 0 ), detail::esft2_deleter_wrapper() );
+ weak_this_ = shared_this_;
         }
     }
 
-#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
-
- template< class U, class Y > friend void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<U> const * pe );
- template< class U, class Y > friend void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<U> const * pe, void * /*pd*/ );
+public: // actually private, but avoids compiler template friendship issues
 
-#else
-
-public:
-
-#endif
-
- template<typename U>
- void sp_accept_owner( shared_ptr<U> & owner ) const
+ // 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
     {
- if( _weak_count.use_count() == 0 )
+ BOOST_ASSERT( ppx != 0 );
+
+ if( weak_this_.use_count() == 0 )
         {
- _weak_count = owner.get_shared_count();
+ weak_this_ = shared_ptr<T>( *ppx, py );
         }
- else if( !_shared_count.empty() )
+ else if( shared_this_.use_count() != 0 )
         {
- BOOST_ASSERT( owner.unique() ); // no weak_ptrs to owner should exist either, but there's no way to check that
- detail::sp_deleter_wrapper * pd = detail::basic_get_deleter<detail::sp_deleter_wrapper>( _shared_count );
+ 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( owner.get_shared_count() );
 
- owner.reset( _shared_count, owner.get() );
- detail::shared_count().swap( _shared_count );
+ pd->set_deleter( *ppx );
+
+ ppx->reset( shared_this_, ppx->get() );
+ shared_this_.reset();
         }
     }
 };
 
-template< class T, class Y > inline void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe )
-{
- if( pe != 0 )
- {
- pe->sp_accept_owner( *ptr );
- }
-}
-
-template< class T, class Y > inline void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe, void * /*pd*/ )
-{
- if( pe != 0 )
- {
- pe->sp_accept_owner( *ptr );
- }
-}
-
 } // namespace boost
 
-#endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+#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-03-22 17:11:17 EDT (Sun, 22 Mar 2009)
@@ -61,6 +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;
 
 namespace detail
 {
@@ -109,6 +110,14 @@
     }
 }
 
+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 ) );
+ }
+}
+
 #ifdef _MANAGED
 
 // Avoid C4793, ... causes native code generation

Modified: trunk/boost/smart_ptr/weak_ptr.hpp
==============================================================================
--- trunk/boost/smart_ptr/weak_ptr.hpp (original)
+++ trunk/boost/smart_ptr/weak_ptr.hpp 2009-03-22 17:11:17 EDT (Sun, 22 Mar 2009)
@@ -124,6 +124,11 @@
         return pn.use_count() == 0;
     }
 
+ bool _empty() const // extension, not in std::weak_ptr
+ {
+ return pn.empty();
+ }
+
     void reset() // never throws in 1.30+
     {
         this_type().swap(*this);

Modified: trunk/libs/smart_ptr/test/Jamfile.v2
==============================================================================
--- trunk/libs/smart_ptr/test/Jamfile.v2 (original)
+++ trunk/libs/smart_ptr/test/Jamfile.v2 2009-03-22 17:11:17 EDT (Sun, 22 Mar 2009)
@@ -56,5 +56,6 @@
           [ run sp_recursive_assign2_test.cpp ]
           [ run sp_recursive_assign_rv_test.cpp ]
           [ run sp_recursive_assign2_rv_test.cpp ]
+ [ run esft_constructor_test.cpp ]
         ;
 }

Copied: trunk/libs/smart_ptr/test/esft_constructor_test.cpp (from r51580, /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-03-22 17:11:17 EDT (Sun, 22 Mar 2009)
@@ -14,13 +14,13 @@
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 
-#include <boost/enable_shared_from_this.hpp>
+#include <boost/smart_ptr/enable_shared_from_this2.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_this< X >
+class X: public boost::enable_shared_from_this2< X >
 {
 private:
 
@@ -75,7 +75,7 @@
     return !(a < b) && !(b < a);
 }
 
-struct Y: public boost::enable_shared_from_this<Y>
+struct Y: public boost::enable_shared_from_this2<Y>
 {};
 
 int main()
@@ -93,8 +93,8 @@
         px.reset();
         BOOST_TEST( early_px.use_count() == 1 );
         BOOST_TEST( X::instances == 1 );
- X::deleter_type *pd = boost::get_deleter<X::deleter_type>(early_px);
- BOOST_TEST(pd && *pd == &X::deleter2 );
+ // X::deleter_type *pd = boost::get_deleter<X::deleter_type>(early_px);
+ // BOOST_TEST(pd && *pd == &X::deleter2 );
     }
 
     BOOST_TEST( X::instances == 0 );
@@ -130,7 +130,7 @@
             x.shared_from_this();
             BOOST_ERROR("x did not throw bad_weak_ptr");
         }
- catch( const boost::bad_weak_ptr &err)
+ catch( const boost::bad_weak_ptr & )
         {}
     }
 
@@ -159,7 +159,7 @@
         {
             y.shared_from_this();
         }
- catch( const boost::bad_weak_ptr &err)
+ catch( const boost::bad_weak_ptr & )
         {
             BOOST_ERROR("y threw 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