diff --git a/boost/smart_ptr/detail/shared_count.hpp b/boost/smart_ptr/detail/shared_count.hpp index f96a220..214e35e 100644 --- a/boost/smart_ptr/detail/shared_count.hpp +++ b/boost/smart_ptr/detail/shared_count.hpp @@ -357,6 +357,11 @@ public: return pi_ != 0? pi_->use_count(): 0; } + long weak_use_count() const // nothrow + { + return pi_ != 0 ? pi_->weak_use_count() : 0; + } + bool unique() const // nothrow { return use_count() == 1; @@ -483,6 +488,11 @@ public: return pi_ != 0? pi_->use_count(): 0; } + long weak_use_count() const // nothrow + { + return pi_ != 0 ? pi_->weak_use_count() : 0; + } + bool empty() const // nothrow { return pi_ == 0; diff --git a/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp b/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp index dffd995..82bdd47 100644 --- a/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp @@ -141,6 +141,11 @@ public: { return static_cast( use_count_ ); // TODO use ld.acq here } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_aix.hpp b/boost/smart_ptr/detail/sp_counted_base_aix.hpp index 0208678..92278a4 100644 --- a/boost/smart_ptr/detail/sp_counted_base_aix.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_aix.hpp @@ -133,6 +133,11 @@ public: { return fetch_and_add( const_cast(&use_count_), 0 ); } + + long weak_use_count() const // nothrow + { + return fetch_and_add( const_cast(&weak_count_), 0) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp b/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp index 51ac56a..0f716e8 100644 --- a/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp @@ -161,6 +161,11 @@ public: { return static_cast( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp b/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp index 1234e78..29fa288 100644 --- a/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_cw_x86.hpp @@ -149,6 +149,11 @@ public: { return static_cast( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp index d122a49..b3d8a64 100644 --- a/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp @@ -148,6 +148,11 @@ public: { return static_cast( use_count_ ); // TODO use ld.acq here } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp index 3f1f449..b72b377 100644 --- a/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp @@ -172,6 +172,11 @@ public: { return static_cast( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp index 7f5c414..f8f1048 100644 --- a/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp @@ -172,6 +172,11 @@ public: { return static_cast( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp index 21fa59d..bd3c128 100644 --- a/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp @@ -157,6 +157,11 @@ public: { return const_cast< int32_t const volatile & >( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast< int32_t const volatile & >( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp index 4d7fa8d..7986747 100644 --- a/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp @@ -164,6 +164,11 @@ public: { return static_cast( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_nt.hpp b/boost/smart_ptr/detail/sp_counted_base_nt.hpp index dfd70e7..cf9951e 100644 --- a/boost/smart_ptr/detail/sp_counted_base_nt.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_nt.hpp @@ -98,6 +98,11 @@ public: { return use_count_; } + + long weak_use_count() const // nothrow + { + return weak_count_ - (use_count_ != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_pt.hpp b/boost/smart_ptr/detail/sp_counted_base_pt.hpp index 3c56fec..683f592 100644 --- a/boost/smart_ptr/detail/sp_counted_base_pt.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_pt.hpp @@ -126,6 +126,15 @@ public: return r; } + + long weak_use_count() const // nothrow + { + pthread_mutex_lock( &m_ ); + long r = weak_count_ - (use_count_ != 0); + pthread_mutex_unlock( &m_ ); + + return r; + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp b/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp index e51e676..042f6ce 100644 --- a/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp @@ -152,6 +152,11 @@ public: { return const_cast< uint32_t const volatile & >( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast< uint32_t const volatile & >( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_solaris.hpp b/boost/smart_ptr/detail/sp_counted_base_solaris.hpp index d1b6bec..fa2b865 100644 --- a/boost/smart_ptr/detail/sp_counted_base_solaris.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_solaris.hpp @@ -104,6 +104,11 @@ public: { return static_cast( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_spin.hpp b/boost/smart_ptr/detail/sp_counted_base_spin.hpp index bbd11e6..13af5d2 100644 --- a/boost/smart_ptr/detail/sp_counted_base_spin.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_spin.hpp @@ -122,6 +122,12 @@ public: spinlock_pool<1>::scoped_lock lock( &use_count_ ); return use_count_; } + + long weak_use_count() const // nothrow + { + spinlock_pool<1>::scoped_lock lock( &use_count_ ); + return weak_count_ - (use_count_ != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_sync.hpp b/boost/smart_ptr/detail/sp_counted_base_sync.hpp index 41f654e..58cdc9d 100644 --- a/boost/smart_ptr/detail/sp_counted_base_sync.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_sync.hpp @@ -146,6 +146,11 @@ public: { return const_cast< sp_int32_t const volatile & >( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast< sp_int32_t const volatile & >( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp b/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp index 842f58f..b8b65a3 100644 --- a/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp @@ -141,6 +141,11 @@ public: { return *const_cast(&use_count_); } + + long weak_use_count() const // nothrow + { + return *const_cast(&weak_count_) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/detail/sp_counted_base_w32.hpp b/boost/smart_ptr/detail/sp_counted_base_w32.hpp index 06aa456..155e266 100644 --- a/boost/smart_ptr/detail/sp_counted_base_w32.hpp +++ b/boost/smart_ptr/detail/sp_counted_base_w32.hpp @@ -121,6 +121,11 @@ public: { return static_cast( use_count_ ); } + + long weak_use_count() const // nothrow + { + return static_cast( weak_count_ ) - (use_count() != 0); + } }; } // namespace detail diff --git a/boost/smart_ptr/shared_ptr.hpp b/boost/smart_ptr/shared_ptr.hpp index 0932cc3..8af7f9a 100644 --- a/boost/smart_ptr/shared_ptr.hpp +++ b/boost/smart_ptr/shared_ptr.hpp @@ -437,6 +437,11 @@ public: return pn.use_count(); } + long weak_use_count() const // never throws + { + return pn.weak_use_count(); + } + void swap(shared_ptr & other) // never throws { std::swap(px, other.px); diff --git a/boost/smart_ptr/weak_ptr.hpp b/boost/smart_ptr/weak_ptr.hpp index 5391910..7a24758 100644 --- a/boost/smart_ptr/weak_ptr.hpp +++ b/boost/smart_ptr/weak_ptr.hpp @@ -173,6 +173,11 @@ public: return pn.use_count(); } + long weak_use_count() const // never throws + { + return pn.weak_use_count(); + } + bool expired() const // never throws { return pn.use_count() == 0; diff --git a/libs/smart_ptr/shared_ptr.htm b/libs/smart_ptr/shared_ptr.htm index 77e1fa8..240d8dc 100644 --- a/libs/smart_ptr/shared_ptr.htm +++ b/libs/smart_ptr/shared_ptr.htm @@ -136,6 +136,7 @@ void bad() bool unique() const; // never throws long use_count() const; // never throws + long weak_use_count() const; // never throws operator unspecified-bool-type() const; // never throws @@ -384,6 +385,15 @@ q = p;

Notes: use_count() is not necessarily efficient. Use only for debugging and testing purposes, not for production code.

+

weak_use_count

+
long weak_use_count() const; // never throws
+
+

Returns: the number of weak_ptr objects that share ownership with *this, + or 0 when *this is empty.

+

Throws: nothing.

+

Notes: weak_use_count() is not necessarily efficient. Use only + for debugging and testing purposes, not for production code.

+

conversions

operator unspecified-bool-type () const; // never throws
@@ -672,7 +682,7 @@ p3.reset(new int(2)); // undefined, multiple writes

A. Automatic conversion is believed to be too error prone.

-

Q. Why does shared_ptr supply use_count()?

+

Q. Why does shared_ptr supply use_count()/weak_use_count()?

A. As an aid to writing test cases and debugging displays. One of the progenitors had use_count(), and it was useful in tracking down bugs in a diff --git a/libs/smart_ptr/test/weak_ptr_test.cpp b/libs/smart_ptr/test/weak_ptr_test.cpp index a4ad766..819427f 100644 --- a/libs/smart_ptr/test/weak_ptr_test.cpp +++ b/libs/smart_ptr/test/weak_ptr_test.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -76,16 +77,19 @@ void default_constructor() { boost::weak_ptr wp; BOOST_TEST(wp.use_count() == 0); + BOOST_TEST(wp.weak_use_count() == 0); } { boost::weak_ptr wp; BOOST_TEST(wp.use_count() == 0); + BOOST_TEST(wp.weak_use_count() == 0); } { boost::weak_ptr wp; BOOST_TEST(wp.use_count() == 0); + BOOST_TEST(wp.weak_use_count() == 0); } } @@ -96,9 +100,13 @@ void shared_ptr_constructor() boost::weak_ptr wp(sp); BOOST_TEST(wp.use_count() == sp.use_count()); + BOOST_TEST(wp.weak_use_count() == 0); + BOOST_TEST(wp.weak_use_count() == sp.weak_use_count()); boost::weak_ptr wp2(sp); BOOST_TEST(wp2.use_count() == sp.use_count()); + BOOST_TEST(wp2.weak_use_count() == 0); + BOOST_TEST(wp2.weak_use_count() == wp.weak_use_count()); } { @@ -108,8 +116,10 @@ void shared_ptr_constructor() boost::weak_ptr wp(sp); BOOST_TEST(wp.use_count() == sp.use_count()); BOOST_TEST(wp.use_count() == 1); + BOOST_TEST(wp.weak_use_count() == 1); boost::shared_ptr sp2(wp); BOOST_TEST(wp.use_count() == 2); + BOOST_TEST(wp.weak_use_count() == 1); BOOST_TEST(!(sp < sp2 || sp2 < sp)); } @@ -117,8 +127,10 @@ void shared_ptr_constructor() boost::weak_ptr wp(sp); BOOST_TEST(wp.use_count() == sp.use_count()); BOOST_TEST(wp.use_count() == 1); + BOOST_TEST(wp.weak_use_count() == 1); boost::shared_ptr sp2(wp); BOOST_TEST(wp.use_count() == 2); + BOOST_TEST(wp.weak_use_count() == 1); BOOST_TEST(!(sp < sp2 || sp2 < sp)); } } @@ -130,8 +142,10 @@ void shared_ptr_constructor() boost::weak_ptr wp(sp); BOOST_TEST(wp.use_count() == sp.use_count()); BOOST_TEST(wp.use_count() == 1); + BOOST_TEST(wp.weak_use_count() == 1); boost::shared_ptr sp2(wp); BOOST_TEST(wp.use_count() == 2); + BOOST_TEST(wp.weak_use_count() == 1); BOOST_TEST(!(sp < sp2 || sp2 < sp)); } @@ -139,8 +153,10 @@ void shared_ptr_constructor() boost::weak_ptr wp(sp); BOOST_TEST(wp.use_count() == sp.use_count()); BOOST_TEST(wp.use_count() == 1); + BOOST_TEST(wp.weak_use_count() == 1); boost::shared_ptr sp2(wp); BOOST_TEST(wp.use_count() == 2); + BOOST_TEST(wp.weak_use_count() == 1); BOOST_TEST(!(sp < sp2 || sp2 < sp)); } } @@ -150,6 +166,7 @@ void shared_ptr_constructor() boost::weak_ptr wp(sp); BOOST_TEST(wp.use_count() == sp.use_count()); + BOOST_TEST(wp.weak_use_count() == sp.weak_use_count()); } { @@ -224,7 +241,9 @@ void copy_constructor() boost::weak_ptr wp; boost::weak_ptr wp2(wp); BOOST_TEST(wp2.use_count() == wp.use_count()); + BOOST_TEST(wp2.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp2.use_count() == 0); + BOOST_TEST(wp2.weak_use_count() == 0); } { @@ -238,7 +257,9 @@ void copy_constructor() boost::weak_ptr wp; boost::weak_ptr wp2(wp); BOOST_TEST(wp2.use_count() == wp.use_count()); + BOOST_TEST(wp2.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp2.use_count() == 0); + BOOST_TEST(wp2.weak_use_count() == 0); } { @@ -247,7 +268,9 @@ void copy_constructor() boost::weak_ptr wp2(wp); BOOST_TEST(wp2.use_count() == wp.use_count()); + BOOST_TEST(wp2.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp2.use_count() == 1); + BOOST_TEST(wp2.weak_use_count() == 2); BOOST_TEST(!(wp < wp2 || wp2 < wp)); sp.reset(); @@ -255,7 +278,9 @@ void copy_constructor() boost::weak_ptr wp3(wp); BOOST_TEST(wp3.use_count() == wp.use_count()); + BOOST_TEST(wp3.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp3.use_count() == 0); + BOOST_TEST(wp3.weak_use_count() == 3); BOOST_TEST(!(wp < wp3 || wp3 < wp)); } @@ -265,7 +290,9 @@ void copy_constructor() boost::weak_ptr wp2(wp); BOOST_TEST(wp2.use_count() == wp.use_count()); + BOOST_TEST(wp2.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp2.use_count() == 1); + BOOST_TEST(wp2.weak_use_count() == 2); BOOST_TEST(!(wp < wp2 || wp2 < wp)); sp.reset(); @@ -273,7 +300,9 @@ void copy_constructor() boost::weak_ptr wp3(wp); BOOST_TEST(wp3.use_count() == wp.use_count()); + BOOST_TEST(wp3.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp3.use_count() == 0); + BOOST_TEST(wp3.weak_use_count() == 3); BOOST_TEST(!(wp < wp3 || wp3 < wp)); } @@ -283,7 +312,9 @@ void copy_constructor() boost::weak_ptr wp2(wp); BOOST_TEST(wp2.use_count() == wp.use_count()); + BOOST_TEST(wp2.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp2.use_count() == 1); + BOOST_TEST(wp2.weak_use_count() == 2); BOOST_TEST(!(wp < wp2 || wp2 < wp)); sp.reset(); @@ -291,7 +322,9 @@ void copy_constructor() boost::weak_ptr wp3(wp); BOOST_TEST(wp3.use_count() == wp.use_count()); + BOOST_TEST(wp3.weak_use_count() == wp.weak_use_count()); BOOST_TEST(wp3.use_count() == 0); + BOOST_TEST(wp3.weak_use_count() == 3); BOOST_TEST(!(wp < wp3 || wp3 < wp)); } diff --git a/libs/smart_ptr/weak_ptr.htm b/libs/smart_ptr/weak_ptr.htm index 0fa87f7..b839e30 100644 --- a/libs/smart_ptr/weak_ptr.htm +++ b/libs/smart_ptr/weak_ptr.htm @@ -87,6 +87,7 @@ if(shared_ptr<int> r = q.lock()) template<class Y> weak_ptr & operator=(shared_ptr<Y> const & r); long use_count() const; + long weak_use_count() const; bool expired() const; shared_ptr<T> lock() const; @@ -151,6 +152,15 @@ template<class Y> weak_ptr & operator=(shared_ptr<Y> const &

Notes: use_count() is not necessarily efficient. Use only for debugging and testing purposes, not for production code.

+

weak_use_count

+
long weak_use_count() const;
+
+

Returns: 0 if *this is empty; otherwise, the + number of weak_ptr objects that share ownership with *this.

+

Throws: nothing.

+

Notes: weak_use_count() is not necessarily efficient. Use only + for debugging and testing purposes, not for production code.

+

expired

bool expired() const;