|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r51485 - trunk/boost
From: pdimov_at_[hidden]
Date: 2009-02-28 15:02:14
Author: pdimov
Date: 2009-02-28 15:02:12 EST (Sat, 28 Feb 2009)
New Revision: 51485
URL: http://svn.boost.org/trac/boost/changeset/51485
Log:
Sync enable_shared_from_this.hpp and shared_ptr.hpp with release.
Text files modified:
trunk/boost/enable_shared_from_this.hpp | 95 ++++------------------
trunk/boost/shared_ptr.hpp | 165 +++++++++++----------------------------
2 files changed, 65 insertions(+), 195 deletions(-)
Modified: trunk/boost/enable_shared_from_this.hpp
==============================================================================
--- trunk/boost/enable_shared_from_this.hpp (original)
+++ trunk/boost/enable_shared_from_this.hpp 2009-02-28 15:02:12 EST (Sat, 28 Feb 2009)
@@ -13,23 +13,15 @@
// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
//
-#include <boost/config.hpp>
+#include <boost/weak_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/assert.hpp>
-#include <boost/detail/workaround.hpp>
+#include <boost/config.hpp>
namespace boost
{
-#if !defined( BOOST_NO_MEMBER_TEMPLATE_FRIENDS )
-
-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*/ );
-
-#endif
-
-template< class T > class enable_shared_from_this
+template<class T> class enable_shared_from_this
{
protected:
@@ -46,89 +38,36 @@
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_this()
{
- BOOST_ASSERT( _shared_count.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
}
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 );
+ shared_ptr<T> p(_internal_weak_this);
+ BOOST_ASSERT(p.get() == this);
+ return p;
}
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 );
- }
-
-private:
-
- mutable detail::weak_count _weak_count;
- mutable detail::shared_count _shared_count;
-
- void init_weak_once() const
- {
- if( _weak_count.empty() )
- {
- detail::shared_count( (void*)0, detail::sp_deleter_wrapper() ).swap( _shared_count );
- _weak_count = _shared_count;
- }
+ shared_ptr<T const> p(_internal_weak_this);
+ BOOST_ASSERT(p.get() == this);
+ return p;
}
-#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*/ );
-
-#else
-
-public:
-
-#endif
+// Note: No, you don't need to initialize _internal_weak_this
+//
+// Please read the documentation, not the code
+//
+// http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
- template<typename U>
- void sp_accept_owner( shared_ptr<U> & owner ) const
- {
- if( _weak_count.use_count() == 0 )
- {
- _weak_count = owner.get_shared_count();
- }
- else if( !_shared_count.empty() )
- {
- 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( pd != 0 );
- pd->set_deleter( owner.get_shared_count() );
-
- owner.reset( _shared_count, owner.get() );
- detail::shared_count().swap( _shared_count );
- }
- }
+ typedef T _internal_element_type; // for bcc 5.5.1
+ mutable weak_ptr<_internal_element_type> _internal_weak_this;
};
-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
Modified: trunk/boost/shared_ptr.hpp
==============================================================================
--- trunk/boost/shared_ptr.hpp (original)
+++ trunk/boost/shared_ptr.hpp 2009-02-28 15:02:12 EST (Sat, 28 Feb 2009)
@@ -58,8 +58,8 @@
namespace boost
{
-template<class T> class shared_ptr;
template<class T> class weak_ptr;
+template<class T> class enable_shared_from_this;
namespace detail
{
@@ -98,24 +98,12 @@
#endif
-#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
-
-// rvalue auto_ptr support based on a technique by Dave Abrahams
-
-template< class T, class R > struct sp_enable_if_auto_ptr
-{
-};
+// enable_shared_from_this support
-template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
+template<class T, class Y> void sp_enable_shared_from_this( shared_count const & pn, boost::enable_shared_from_this<T> const * pe, Y const * px )
{
- typedef R type;
-};
-
-#endif
-
-} // namespace detail
-
-// sp_accept_owner
+ if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast<Y*>(px), pn);
+}
#ifdef _MANAGED
@@ -126,22 +114,45 @@
template<class T> sp_any_pointer( T* ) {}
};
-inline void sp_accept_owner( sp_any_pointer, sp_any_pointer )
-{
-}
-
-inline void sp_accept_owner( sp_any_pointer, sp_any_pointer, sp_any_pointer )
+inline void sp_enable_shared_from_this( shared_count const & /*pn*/, sp_any_pointer, sp_any_pointer )
{
}
#else // _MANAGED
-inline void sp_accept_owner( ... )
+#ifdef sgi
+// Turn off: the last argument of the varargs function "sp_enable_shared_from_this" is unnamed
+# pragma set woff 3506
+#endif
+
+inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... )
{
}
+#ifdef sgi
+# pragma reset woff 3506
+#endif
+
#endif // _MANAGED
+#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
+
+// rvalue auto_ptr support based on a technique by Dave Abrahams
+
+template< class T, class R > struct sp_enable_if_auto_ptr
+{
+};
+
+template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
+{
+ typedef R type;
+};
+
+#endif
+
+} // namespace detail
+
+
//
// shared_ptr
//
@@ -171,7 +182,7 @@
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
{
- sp_accept_owner( this, p );
+ boost::detail::sp_enable_shared_from_this( pn, p, p );
}
//
@@ -180,18 +191,16 @@
// shared_ptr will release p by calling d(p)
//
- template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
+ template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d)
{
- D * pd = static_cast<D *>( pn.get_deleter( BOOST_SP_TYPEID(D) ) );
- sp_accept_owner( this, p, pd );
+ boost::detail::sp_enable_shared_from_this( pn, p, p );
}
// As above, but with allocator. A's copy constructor shall not throw.
template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
{
- D * pd = static_cast<D *>( pn.get_deleter( BOOST_SP_TYPEID(D) ) );
- sp_accept_owner( this, p, pd );
+ boost::detail::sp_enable_shared_from_this( pn, p, p );
}
// generated copy constructor, assignment, destructor are fine...
@@ -238,10 +247,6 @@
{
}
- shared_ptr( detail::shared_count const & c, T * p ): px( p ), pn( c ) // never throws
- {
- }
-
// aliasing
template< class Y >
shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
@@ -283,8 +288,7 @@
{
Y * tmp = r.get();
pn = boost::detail::shared_count(r);
-
- sp_accept_owner( this, tmp );
+ boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
}
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
@@ -294,8 +298,7 @@
{
typename Ap::element_type * tmp = r.get();
pn = boost::detail::shared_count( r );
-
- sp_accept_owner( this, tmp );
+ boost::detail::sp_enable_shared_from_this( pn, tmp, tmp );
}
@@ -364,10 +367,6 @@
r.px = 0;
}
- shared_ptr(detail::shared_count && c, T * 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 );
@@ -409,18 +408,6 @@
this_type( r, p ).swap( *this );
}
- void reset( detail::shared_count const & c, T * p )
- {
- this_type( c, p ).swap( *this );
- }
-
-#if defined( BOOST_HAS_RVALUE_REFS )
- void reset( detail::shared_count && c, T * p )
- {
- this_type( static_cast< detail::shared_count && >( c ), p ).swap( *this );
- }
-#endif
-
reference operator* () const // never throws
{
BOOST_ASSERT(px != 0);
@@ -506,14 +493,14 @@
pn.swap(other.pn);
}
- detail::shared_count const & get_shared_count() const // never throws
+ template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
{
- return pn;
+ return pn < rhs.pn;
}
- template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
+ void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
{
- return pn < rhs.pn;
+ return pn.get_deleter( ti );
}
bool _internal_equiv( shared_ptr const & r ) const
@@ -652,8 +639,6 @@
// 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) )
@@ -661,75 +646,21 @@
// g++ 2.9x doesn't allow static_cast<X const *>(void *)
// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
-template<class D> D * basic_get_deleter(shared_count const & c)
+template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
- void const * q = c.get_deleter(BOOST_SP_TYPEID(D));
+ void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
return const_cast<D *>(static_cast<D const *>(q));
}
#else
-template<class D> D * basic_get_deleter(shared_count const & c)
+template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
{
- return static_cast<D *>(c.get_deleter(BOOST_SP_TYPEID(D)));
+ return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
}
#endif
-class sp_deleter_wrapper
-{
- detail::shared_count _deleter;
-public:
- sp_deleter_wrapper()
- {}
- void set_deleter(shared_count const &deleter)
- {
- _deleter = deleter;
- }
- void operator()(const void *)
- {
- BOOST_ASSERT(_deleter.use_count() <= 1);
- detail::shared_count().swap( _deleter );
- }
- template<typename D>
-#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 )
- D* get_deleter( D* ) const
-#else
- D* get_deleter() const
-#endif
- {
- return boost::detail::basic_get_deleter<D>(_deleter);
- }
-};
-
-} // namespace detail
-
-template<class D, class T> D * get_deleter( shared_ptr<T> const & p )
-{
- D *del = detail::basic_get_deleter<D>( p.get_shared_count() );
-
- if( del == 0 )
- {
- detail::sp_deleter_wrapper *del_wrapper = detail::basic_get_deleter<detail::sp_deleter_wrapper>(p.get_shared_count());
-
-#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 )
-
- if( del_wrapper ) del = del_wrapper->get_deleter( (D*)0 );
-
-#elif defined( __GNUC__ ) && BOOST_WORKAROUND( __GNUC__, < 4 )
-
- if( del_wrapper ) del = del_wrapper->::boost::detail::sp_deleter_wrapper::get_deleter<D>();
-
-#else
-
- if( del_wrapper ) del = del_wrapper->get_deleter<D>();
-
-#endif
- }
-
- return del;
-}
-
// atomic access
#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
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