|
Boost-Commit : |
From: pdimov_at_[hidden]
Date: 2008-04-12 14:22:19
Author: pdimov
Date: 2008-04-12 14:22:18 EDT (Sat, 12 Apr 2008)
New Revision: 44353
URL: http://svn.boost.org/trac/boost/changeset/44353
Log:
sp_accept_owner added.
Added:
trunk/libs/smart_ptr/test/sp_accept_owner_test.cpp (contents, props changed)
Text files modified:
trunk/boost/enable_shared_from_this.hpp | 26 +++++++++++-
trunk/boost/shared_ptr.hpp | 81 +++++++++++++++------------------------
trunk/libs/smart_ptr/test/Jamfile.v2 | 1
trunk/libs/smart_ptr/test/esft_constructor_test.cpp | 2
4 files changed, 56 insertions(+), 54 deletions(-)
Modified: trunk/boost/enable_shared_from_this.hpp
==============================================================================
--- trunk/boost/enable_shared_from_this.hpp (original)
+++ trunk/boost/enable_shared_from_this.hpp 2008-04-12 14:22:18 EDT (Sat, 12 Apr 2008)
@@ -27,10 +27,10 @@
// to use lazy initialization
void init_internal_shared_once() const
{
- if(owned() == false && _internal_shared_this == 0)
+ if( !owned() && _internal_shared_this.get() == 0 )
{
- _internal_shared_this = shared_ptr<T>(dynamic_cast<T *>(const_cast<enable_shared_from_this*>(this)),
- detail::sp_deleter_wrapper(), detail::ignore_enable_shared_from_this_tag());
+ T * p = dynamic_cast<T *>(const_cast<enable_shared_from_this*>(this));
+ _internal_shared_this = shared_ptr<T>( p, detail::sp_deleter_wrapper() );
BOOST_ASSERT(_internal_shared_this.get() == this);
_internal_weak_this = _internal_shared_this;
}
@@ -109,6 +109,26 @@
}
};
+template< class T, class Y > inline void sp_accept_owner( boost::shared_ptr<Y> * ptr, boost::enable_shared_from_this<T> const * pe )
+{
+ if( pe != 0 )
+ {
+ pe->_internal_accept_owner( *ptr );
+ }
+}
+
+template< class T, class Y > inline void sp_accept_owner( boost::shared_ptr<Y> * ptr, boost::enable_shared_from_this<T> const * pe, void * /*pd*/ )
+{
+ if( pe != 0 )
+ {
+ pe->_internal_accept_owner( *ptr );
+ }
+}
+
+template< class T, class Y > inline void sp_accept_owner( boost::shared_ptr<Y> * /*ptr*/, boost::enable_shared_from_this<T> const * /*pe*/, boost::detail::sp_deleter_wrapper * /*pd*/ )
+{
+}
+
} // 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 2008-04-12 14:22:18 EDT (Sat, 12 Apr 2008)
@@ -50,7 +50,6 @@
template<class T> class shared_ptr;
template<class T> class weak_ptr;
-template<class T> class enable_shared_from_this;
namespace detail
{
@@ -89,17 +88,24 @@
#endif
-// enable_shared_from_this support
+#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
-struct ignore_enable_shared_from_this_tag {};
+// rvalue auto_ptr support based on a technique by Dave Abrahams
-template<class T, class Y> void sp_enable_shared_from_this( boost::shared_ptr<Y> * ptr, boost::enable_shared_from_this<T> const * pe )
+template< class T, class R > struct sp_enable_if_auto_ptr
{
- if(pe != 0)
- {
- pe->_internal_accept_owner(*ptr);
- }
-}
+};
+
+template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
+{
+ typedef R type;
+};
+
+#endif
+
+} // namespace detail
+
+// sp_accept_owner
#ifdef _MANAGED
@@ -110,44 +116,21 @@
template<class T> sp_any_pointer( T* ) {}
};
-inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer )
+inline void sp_accept_owner( sp_any_pointer, sp_any_pointer )
{
}
-#else // _MANAGED
-
-#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( ... )
+inline void sp_accept_owner( sp_any_pointer, sp_any_pointer, sp_any_pointer )
{
}
-#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
-{
-};
+#else // _MANAGED
-template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
+inline void sp_accept_owner( ... )
{
- typedef R type;
-};
-
-#endif
-
-} // namespace detail
+}
+#endif // _MANAGED
//
// shared_ptr
@@ -178,7 +161,7 @@
template<class Y>
explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
{
- boost::detail::sp_enable_shared_from_this( this, p );
+ sp_accept_owner( this, p );
}
//
@@ -187,16 +170,18 @@
// 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 )
{
- boost::detail::sp_enable_shared_from_this( this, p );
+ D * pd = static_cast<D *>( pn.get_deleter( BOOST_SP_TYPEID(D) ) );
+ sp_accept_owner( this, p, pd );
}
// 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 )
{
- boost::detail::sp_enable_shared_from_this( this, p );
+ D * pd = static_cast<D *>( pn.get_deleter( BOOST_SP_TYPEID(D) ) );
+ sp_accept_owner( this, p, pd );
}
// generated copy constructor, assignment, destructor are fine...
@@ -268,12 +253,6 @@
}
}
-// constructor that doesn't trigger enable_shared_from_this code, needed
-// for enable_shared_from_this internal implementation
- template<class Y, class D> shared_ptr(Y * p, D d, detail::ignore_enable_shared_from_this_tag):
- px(p), pn(p, d)
- {}
-
#ifndef BOOST_NO_AUTO_PTR
template<class Y>
@@ -281,7 +260,8 @@
{
Y * tmp = r.get();
pn = boost::detail::shared_count(r);
- boost::detail::sp_enable_shared_from_this( this, tmp );
+
+ sp_accept_owner( this, tmp );
}
#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
@@ -291,7 +271,8 @@
{
typename Ap::element_type * tmp = r.get();
pn = boost::detail::shared_count( r );
- boost::detail::sp_enable_shared_from_this( this, tmp );
+
+ sp_accept_owner( this, tmp );
}
Modified: trunk/libs/smart_ptr/test/Jamfile.v2
==============================================================================
--- trunk/libs/smart_ptr/test/Jamfile.v2 (original)
+++ trunk/libs/smart_ptr/test/Jamfile.v2 2008-04-12 14:22:18 EDT (Sat, 12 Apr 2008)
@@ -43,5 +43,6 @@
[ run spinlock_try_test.cpp ]
[ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
[ run spinlock_pool_test.cpp ]
+ [ run sp_accept_owner_test.cpp ]
;
}
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 2008-04-12 14:22:18 EDT (Sat, 12 Apr 2008)
@@ -72,7 +72,7 @@
template<typename T, typename U>
bool are_shared_owners(const boost::shared_ptr<T> &a, const boost::shared_ptr<U> &b)
{
- return a && !(a < b) && !(b < a);
+ return !(a < b) && !(b < a);
}
struct Y: public boost::enable_shared_from_this<Y>
Added: trunk/libs/smart_ptr/test/sp_accept_owner_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/sp_accept_owner_test.cpp 2008-04-12 14:22:18 EDT (Sat, 12 Apr 2008)
@@ -0,0 +1,146 @@
+//
+// sp_accept_owner_test.cpp
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// 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/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+namespace N
+{
+
+struct D;
+
+struct X
+{
+ X * px_;
+
+ D * pd_;
+ void * pv_;
+
+ X(): px_( 0 ), pd_( 0 ), pv_( 0 )
+ {
+ }
+};
+
+struct D
+{
+ template<class T> void operator()( T * p ) const { delete p; }
+};
+
+} // namespace N
+
+#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP )
+
+namespace N
+{
+
+#else
+
+namespace boost
+{
+
+#endif
+
+template<class Y> inline void sp_accept_owner( boost::shared_ptr<Y> * ps, ::N::X * px )
+{
+ std::cout << "sp_accept_owner( " << ps << ", " << px << " )\n";
+
+ BOOST_TEST( ps->get() == px );
+
+ if( px != 0 )
+ {
+ px->px_ = px;
+ }
+}
+
+template<class Y> inline void sp_accept_owner( boost::shared_ptr<Y> * ps, ::N::X * px, ::N::D * pd )
+{
+ std::cout << "sp_accept_owner( " << ps << ", " << px << ", (D*)" << pd << " )\n";
+
+ BOOST_TEST( ps->get() == px );
+
+ if( px != 0 )
+ {
+ px->px_ = px;
+ px->pd_ = pd;
+ }
+}
+
+template<class Y> inline void sp_accept_owner( boost::shared_ptr<Y> * ps, ::N::X * px, void * pv )
+{
+ std::cout << "sp_accept_owner( " << ps << ", " << px << ", (void*)" << pv << " )\n";
+
+ BOOST_TEST( ps->get() == px );
+
+ if( px != 0 )
+ {
+ px->px_ = px;
+ px->pv_ = pv;
+ }
+}
+
+} // namespace N or boost
+
+struct D2
+{
+ template<class T> void operator()( T * p ) const { delete p; }
+};
+
+template<class T> void test( T* = 0 )
+{
+ {
+ boost::shared_ptr<T> p( static_cast< T* >( 0 ) );
+ }
+
+ {
+ T * p = new T;
+ boost::shared_ptr<T> q( p );
+
+ BOOST_TEST( q->px_ == p );
+ BOOST_TEST( q->pd_ == 0 );
+ BOOST_TEST( q->pv_ == 0 );
+ }
+
+ {
+ T * p = new T;
+ boost::shared_ptr<T> q( p, N::D() );
+
+ BOOST_TEST( q->px_ == p );
+ BOOST_TEST( q->pd_ != 0 );
+ BOOST_TEST( q->pv_ == 0 );
+ }
+
+ {
+ T * p = new T;
+ boost::shared_ptr<T> q( p, D2() );
+
+ BOOST_TEST( q->px_ == p );
+ BOOST_TEST( q->pd_ == 0 );
+ BOOST_TEST( q->pv_ != 0 );
+ }
+}
+
+namespace N2
+{
+
+struct Y: public virtual N::X
+{
+};
+
+} // namespace N2
+
+int main()
+{
+ test<N::X>();
+ test<N2::Y>();
+
+ return boost::report_errors();
+}
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