diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index 69bff58..b6bf44c 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -327,6 +327,11 @@ public: this_type( p, d, a ).swap( *this ); } + template void reset( shared_ptr const & r, T * p ) + { + this_type( r, p ).swap( *this ); + } + reference operator* () const // never throws { BOOST_ASSERT(px != 0); diff --git a/shared_ptr.htm b/shared_ptr.htm index 71cb9c9..e2626fc 100644 --- a/shared_ptr.htm +++ b/shared_ptr.htm @@ -111,6 +111,7 @@ void bad() shared_ptr(shared_ptr const & r); // never throws template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws + template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws template<class Y> explicit shared_ptr(weak_ptr<Y> const & r); template<class Y> explicit shared_ptr(std::auto_ptr<Y> & r); @@ -122,6 +123,7 @@ void bad() template<class Y> void reset(Y * p); template<class Y, class D> void reset(Y * p, D d); template<class Y, class D, class A> void reset(Y * p, D d, A a); + template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws T & operator*() const; // never throws T * operator->() const; // never throws @@ -253,6 +255,13 @@ template<class Y> shared_ptr(shared_ptr<Y> const & r); // never r.use_count().

Throws: nothing.

+
template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p); // never throws
+
+

Effects: constructs a shared_ptr that shares ownership with + r and stores p.

+

Postconditions: get() == p && use_count() == r.use_count().

+

Throws: nothing.

+
template<class Y> explicit shared_ptr(weak_ptr<Y> const & r);

Effects: Constructs a shared_ptr that shares ownership with @@ -328,6 +337,10 @@ q = p;

Effects: Equivalent to shared_ptr(p, d, a).swap(*this).

+
template<class Y> void reset(shared_ptr<Y> const & r, T * p); // never throws
+
+

Effects: Equivalent to shared_ptr(r, p).swap(*this).

+

indirection

T & operator*() const; // never throws
diff --git a/test/Jamfile b/test/Jamfile index efc07c3..a28d75d 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -33,6 +33,7 @@ DEPENDS all : smart_ptr ; [ run pointer_cast_test.cpp ] [ compile pointer_to_other_test.cpp ] [ run auto_ptr_rv_test.cpp ] + [ run shared_ptr_alias_test.cpp ] ; # this one is too slow to run unless explicitly requested, and ALL diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 55ee95e..63708b7 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -28,5 +28,6 @@ import testing ; [ run pointer_cast_test.cpp ] [ compile pointer_to_other_test.cpp ] [ run auto_ptr_rv_test.cpp ] + [ run shared_ptr_alias_test.cpp ] ; } diff --git a/test/shared_ptr_alias_test.cpp b/test/shared_ptr_alias_test.cpp new file mode 100644 index 0000000..83d866f --- /dev/null +++ b/test/shared_ptr_alias_test.cpp @@ -0,0 +1,146 @@ +#include + +// shared_ptr_alias_test.cpp +// +// Copyright (c) 2007 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 +#include +#include +#include + +// + +class incomplete; + +struct X +{ + int v_; + + explicit X( int v ): v_( v ) + { + } + + ~X() + { + v_ = 0; + } +}; + +int main() +{ + { + int m = 0; + boost::shared_ptr< int > p; + boost::shared_ptr< int > p2( p, &m ); + + BOOST_TEST( p2.get() == &m ); + BOOST_TEST( p2? true: false ); + BOOST_TEST( !!p2 ); + BOOST_TEST( p2.use_count() == p.use_count() ); + BOOST_TEST( !( p < p2 ) && !( p2 < p ) ); + + p2.reset( p, 0 ); + + BOOST_TEST( p2.get() == 0 ); + BOOST_TEST( p2? false: true ); + BOOST_TEST( !p2 ); + BOOST_TEST( p2.use_count() == p.use_count() ); + BOOST_TEST( !( p < p2 ) && !( p2 < p ) ); + } + + { + int m = 0; + boost::shared_ptr< int > p( new int ); + boost::shared_ptr< int const > p2( p, &m ); + + BOOST_TEST( p2.get() == &m ); + BOOST_TEST( p2? true: false ); + BOOST_TEST( !!p2 ); + BOOST_TEST( p2.use_count() == p.use_count() ); + BOOST_TEST( !( p < p2 ) && !( p2 < p ) ); + + boost::shared_ptr< int volatile > p3; + p2.reset( p3, 0 ); + + BOOST_TEST( p2.get() == 0 ); + BOOST_TEST( p2? false: true ); + BOOST_TEST( !p2 ); + BOOST_TEST( p2.use_count() == p3.use_count() ); + BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) ); + } + + { + boost::shared_ptr< int > p( new int ); + boost::shared_ptr< void const > p2( p, 0 ); + + BOOST_TEST( p2.get() == 0 ); + BOOST_TEST( p2? false: true ); + BOOST_TEST( !p2 ); + BOOST_TEST( p2.use_count() == p.use_count() ); + BOOST_TEST( !( p < p2 ) && !( p2 < p ) ); + + int m = 0; + boost::shared_ptr< void volatile > p3; + + p2.reset( p3, &m ); + + BOOST_TEST( p2.get() == &m ); + BOOST_TEST( p2? true: false ); + BOOST_TEST( !!p2 ); + BOOST_TEST( p2.use_count() == p3.use_count() ); + BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) ); + } + + { + boost::shared_ptr< incomplete > p; + boost::shared_ptr< incomplete > p2( p, 0 ); + + BOOST_TEST( p2.get() == 0 ); + BOOST_TEST( p2? false: true ); + BOOST_TEST( !p2 ); + BOOST_TEST( p2.use_count() == p.use_count() ); + BOOST_TEST( !( p < p2 ) && !( p2 < p ) ); + + p2.reset( p, 0 ); + + BOOST_TEST( p2.get() == 0 ); + BOOST_TEST( p2? false: true ); + BOOST_TEST( !p2 ); + BOOST_TEST( p2.use_count() == p.use_count() ); + BOOST_TEST( !( p < p2 ) && !( p2 < p ) ); + } + + { + boost::shared_ptr< X > p( new X( 5 ) ); + boost::shared_ptr< int const > p2( p, &p->v_ ); + + BOOST_TEST( p2.get() == &p->v_ ); + BOOST_TEST( p2? true: false ); + BOOST_TEST( !!p2 ); + BOOST_TEST( p2.use_count() == p.use_count() ); + BOOST_TEST( !( p < p2 ) && !( p2 < p ) ); + + p.reset(); + BOOST_TEST( *p2 == 5 ); + + boost::shared_ptr< X const > p3( new X( 8 ) ); + p2.reset( p3, &p3->v_ ); + + BOOST_TEST( p2.get() == &p3->v_ ); + BOOST_TEST( p2? true: false ); + BOOST_TEST( !!p2 ); + BOOST_TEST( p2.use_count() == p3.use_count() ); + BOOST_TEST( !( p3 < p2 ) && !( p2 < p3 ) ); + + p3.reset(); + BOOST_TEST( *p2 == 8 ); + } + + return boost::report_errors(); +}