diff --git a/include/boost/smart_ptr/intrusive_ptr.hpp b/include/boost/smart_ptr/intrusive_ptr.hpp index 42fdd92..e5db609 100644 --- a/include/boost/smart_ptr/intrusive_ptr.hpp +++ b/include/boost/smart_ptr/intrusive_ptr.hpp @@ -146,6 +146,11 @@ public: this_type( rhs ).swap( *this ); } + void reset( T * rhs, bool add_ref ) + { + this_type( rhs, add_ref ).swap( *this ); + } + T * get() const BOOST_NOEXCEPT { return px; diff --git a/intrusive_ptr.html b/intrusive_ptr.html index 7028444..b7e884b 100644 --- a/intrusive_ptr.html +++ b/intrusive_ptr.html @@ -67,6 +67,7 @@ void reset(); void reset(T * r); + void reset(T * r, bool add_ref); T & operator*() const; // never throws T * operator->() const; // never throws @@ -161,6 +162,10 @@ intrusive_ptr & operator=(T * r);

Effects: Equivalent to intrusive_ptr(r).swap(*this).

+
void reset(T * r, bool add_ref);
+
+

Effects: Equivalent to intrusive_ptr(r, add_ref).swap(*this).

+

indirection

T & operator*() const; // never throws
@@ -307,9 +312,7 @@ intrusive_ptr & operator=(T * r);

- $Date$

-

- Copyright © 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version + Copyright © 2003-2005, 2013 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.

diff --git a/test/intrusive_ptr_test.cpp b/test/intrusive_ptr_test.cpp index b3f50fb..b46ddf3 100644 --- a/test/intrusive_ptr_test.cpp +++ b/test/intrusive_ptr_test.cpp @@ -51,14 +51,18 @@ protected: base(): use_count_(0) { + ++instances; } virtual ~base() { + --instances; } public: + static long instances; + long use_count() const { return use_count_; @@ -91,6 +95,8 @@ public: #endif }; +long base::instances = 0; + } // namespace N #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) @@ -161,19 +167,27 @@ void pointer_constructor() BOOST_TEST(px.get() == 0); } + BOOST_TEST( N::base::instances == 0 ); + { X * p = new X; BOOST_TEST(p->use_count() == 0); + BOOST_TEST( N::base::instances == 1 ); + boost::intrusive_ptr px(p); BOOST_TEST(px.get() == p); BOOST_TEST(px->use_count() == 1); } + BOOST_TEST( N::base::instances == 0 ); + { X * p = new X; BOOST_TEST(p->use_count() == 0); + BOOST_TEST( N::base::instances == 1 ); + #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) using boost::intrusive_ptr_add_ref; #endif @@ -184,6 +198,8 @@ void pointer_constructor() BOOST_TEST(px.get() == p); BOOST_TEST(px->use_count() == 1); } + + BOOST_TEST( N::base::instances == 0 ); } void copy_constructor() @@ -224,17 +240,27 @@ void copy_constructor() BOOST_TEST(px.get() == py.get()); } + BOOST_TEST( N::base::instances == 0 ); + { boost::intrusive_ptr px(new X); boost::intrusive_ptr px2(px); - BOOST_TEST(px2.get() == px.get()); + BOOST_TEST( px2.get() == px.get() ); + + BOOST_TEST( N::base::instances == 1 ); } + BOOST_TEST( N::base::instances == 0 ); + { boost::intrusive_ptr py(new Y); boost::intrusive_ptr px(py); - BOOST_TEST(px.get() == py.get()); + BOOST_TEST( px.get() == py.get() ); + + BOOST_TEST( N::base::instances == 1 ); } + + BOOST_TEST( N::base::instances == 0 ); } void test() @@ -251,15 +277,23 @@ namespace n_destructor void test() { - boost::intrusive_ptr px(new X); - BOOST_TEST(px->use_count() == 1); + BOOST_TEST( N::base::instances == 0 ); { - boost::intrusive_ptr px2(px); - BOOST_TEST(px->use_count() == 2); + boost::intrusive_ptr px(new X); + BOOST_TEST(px->use_count() == 1); + + BOOST_TEST( N::base::instances == 1 ); + + { + boost::intrusive_ptr px2(px); + BOOST_TEST(px->use_count() == 2); + } + + BOOST_TEST(px->use_count() == 1); } - BOOST_TEST(px->use_count() == 1); + BOOST_TEST( N::base::instances == 0 ); } } // namespace n_destructor @@ -288,6 +322,174 @@ void test() } // namespace n_assignment +namespace n_reset +{ + +void test() +{ + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr px; + BOOST_TEST( px.get() == 0 ); + + px.reset(); + BOOST_TEST( px.get() == 0 ); + + X * p = new X; + BOOST_TEST( p->use_count() == 0 ); + BOOST_TEST( N::base::instances == 1 ); + + px.reset( p ); + BOOST_TEST( px.get() == p ); + BOOST_TEST( px->use_count() == 1 ); + + px.reset(); + BOOST_TEST( px.get() == 0 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr px( new X ); + BOOST_TEST( N::base::instances == 1 ); + + px.reset( 0 ); + BOOST_TEST( px.get() == 0 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr px( new X ); + BOOST_TEST( N::base::instances == 1 ); + + px.reset( 0, false ); + BOOST_TEST( px.get() == 0 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr px( new X ); + BOOST_TEST( N::base::instances == 1 ); + + px.reset( 0, true ); + BOOST_TEST( px.get() == 0 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + X * p = new X; + BOOST_TEST( p->use_count() == 0 ); + + BOOST_TEST( N::base::instances == 1 ); + + boost::intrusive_ptr px; + BOOST_TEST( px.get() == 0 ); + + px.reset( p, true ); + BOOST_TEST( px.get() == p ); + BOOST_TEST( px->use_count() == 1 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + X * p = new X; + BOOST_TEST( p->use_count() == 0 ); + + BOOST_TEST( N::base::instances == 1 ); + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + using boost::intrusive_ptr_add_ref; +#endif + intrusive_ptr_add_ref( p ); + BOOST_TEST( p->use_count() == 1 ); + + boost::intrusive_ptr px; + BOOST_TEST( px.get() == 0 ); + + px.reset( p, false ); + BOOST_TEST( px.get() == p ); + BOOST_TEST( px->use_count() == 1 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr px( new X ); + BOOST_TEST( px.get() != 0 ); + BOOST_TEST( px->use_count() == 1 ); + + BOOST_TEST( N::base::instances == 1 ); + + X * p = new X; + BOOST_TEST( p->use_count() == 0 ); + + BOOST_TEST( N::base::instances == 2 ); + + px.reset( p ); + BOOST_TEST( px.get() == p ); + BOOST_TEST( px->use_count() == 1 ); + + BOOST_TEST( N::base::instances == 1 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr px( new X ); + BOOST_TEST( px.get() != 0 ); + BOOST_TEST( px->use_count() == 1 ); + + BOOST_TEST( N::base::instances == 1 ); + + X * p = new X; + BOOST_TEST( p->use_count() == 0 ); + + BOOST_TEST( N::base::instances == 2 ); + + px.reset( p, true ); + BOOST_TEST( px.get() == p ); + BOOST_TEST( px->use_count() == 1 ); + + BOOST_TEST( N::base::instances == 1 ); + } + + BOOST_TEST( N::base::instances == 0 ); + + { + boost::intrusive_ptr px( new X ); + BOOST_TEST( px.get() != 0 ); + BOOST_TEST( px->use_count() == 1 ); + + BOOST_TEST( N::base::instances == 1 ); + + X * p = new X; + BOOST_TEST( p->use_count() == 0 ); + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + using boost::intrusive_ptr_add_ref; +#endif + intrusive_ptr_add_ref( p ); + BOOST_TEST( p->use_count() == 1 ); + + BOOST_TEST( N::base::instances == 2 ); + + px.reset( p, false ); + BOOST_TEST( px.get() == p ); + BOOST_TEST( px->use_count() == 1 ); + + BOOST_TEST( N::base::instances == 1 ); + } + + BOOST_TEST( N::base::instances == 0 ); +} + +} // namespace n_reset + namespace n_access { @@ -572,6 +774,7 @@ int main() n_constructors::test(); n_destructor::test(); n_assignment::test(); + n_reset::test(); n_access::test(); n_swap::test(); n_comparison::test();