From 4653c3673b779b0cfcabb39982af561ac07a960b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 1 May 2002 11:22:22 +0000 Subject: [PATCH] shared_ptr now autodetects counted_bases; minor test updates; intrusive_ptr no longer calls addref/release for NULL pointers. [SVN r13602] --- include/boost/detail/shared_count.hpp | 13 ++++++--- include/boost/intrusive_ptr.hpp | 11 ++++---- include/boost/shared_ptr.hpp | 2 +- shared_ptr_test.cpp | 38 ++++++++++++++++++++++++--- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp index 225a56d..63316f4 100644 --- a/include/boost/detail/shared_count.hpp +++ b/include/boost/detail/shared_count.hpp @@ -169,12 +169,12 @@ private: inline void intrusive_ptr_add_ref(counted_base * p) { - if(p != 0) p->add_ref(); + p->add_ref(); } inline void intrusive_ptr_release(counted_base * p) { - if(p != 0) p->release(); + p->release(); } namespace detail @@ -215,6 +215,8 @@ private: friend class weak_count; + template shared_count(P, D, counted_base const *); + public: shared_count(): pi_(new counted_base(1, 1)) @@ -226,7 +228,7 @@ public: pi_->add_ref(); } - template shared_count(P p, D d): pi_(0) + template shared_count(P p, D d, void const * = 0): pi_(0) { try { @@ -239,6 +241,11 @@ public: } } + template shared_count(P, D, counted_base * pi): pi_(pi) + { + pi_->add_ref(); + } + #ifndef BOOST_NO_AUTO_PTR // auto_ptr is special cased to provide the strong guarantee diff --git a/include/boost/intrusive_ptr.hpp b/include/boost/intrusive_ptr.hpp index 87dbece..780fe78 100644 --- a/include/boost/intrusive_ptr.hpp +++ b/include/boost/intrusive_ptr.hpp @@ -33,7 +33,8 @@ namespace boost // // void intrusive_ptr_add_ref(T * p); // void intrusive_ptr_release(T * p); -// (note: p may be 0!) +// +// (p != 0) // // The object is responsible for destroying itself. // @@ -52,26 +53,26 @@ public: intrusive_ptr(T * p): p_(p) { - intrusive_ptr_add_ref(p_); + if(p_ != 0) intrusive_ptr_add_ref(p_); } ~intrusive_ptr() { - intrusive_ptr_release(p_); + if(p_ != 0) intrusive_ptr_release(p_); } #ifdef BOOST_MSVC6_MEMBER_TEMPLATES template intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.get()) { - intrusive_ptr_add_ref(p_); + if(p_ != 0) intrusive_ptr_add_ref(p_); } #endif intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_) { - intrusive_ptr_add_ref(p_); + if(p_ != 0) intrusive_ptr_add_ref(p_); } #ifdef BOOST_MSVC6_MEMBER_TEMPLATES diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index cf43a1e..39df95f 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -87,7 +87,7 @@ public: } template - explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter()) // Y must be complete + explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter(), p) // Y must be complete { } diff --git a/shared_ptr_test.cpp b/shared_ptr_test.cpp index 9ef6d3d..f96dfc6 100644 --- a/shared_ptr_test.cpp +++ b/shared_ptr_test.cpp @@ -40,7 +40,7 @@ struct X std::cout << "X(" << this << ")::X()\n"; } - virtual ~X() + ~X() // virtual destructor deliberately omitted { --cnt; std::cout << "X(" << this << ")::~X()\n"; @@ -96,6 +96,28 @@ void release_object(int * p) std::cout << "release_object()\n"; } +class Z: public virtual boost::counted_base +{ +public: + + Z() + { + ++cnt; + std::cout << "Z(" << this << ")::Z()\n"; + } + + ~Z() + { + --cnt; + std::cout << "Z(" << this << ")::~Z()\n"; + } + +private: + + Z(Z const &); + Z & operator= (Z const &); +}; + template void test_is_X(boost::shared_ptr const & p) { BOOST_TEST(p->id() == 1); @@ -244,7 +266,7 @@ int test_main(int, char * []) test_is_nonzero(boost::make_shared(wp2)); } - weak_ptr wp3 = shared_dynamic_cast(boost::make_shared(wp2)); + weak_ptr wp3 = shared_dynamic_cast(boost::make_shared(wp2)); BOOST_TEST(wp3.use_count() == 1); BOOST_TEST(wp3.get() != 0); @@ -302,7 +324,17 @@ int test_main(int, char * []) BOOST_TEST(b1 == (wp1 < wp5)); BOOST_TEST(b2 == (wp5 < wp1)); - shared_ptr p6(get_object(), release_object); + { + // note that both get_object and release_object deal with int* + shared_ptr p6(get_object(), release_object); + } + + { + // test intrusive counting + boost::shared_ptr pv(new Z); + boost::shared_ptr pz = boost::shared_static_cast(pv); + BOOST_TEST(pz.use_count() == pz->use_count()); + } } BOOST_TEST(cnt == 0);