From f85a1bf4063886595140599287d0821d37afeab7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 12 Apr 2008 14:27:22 +0000 Subject: [PATCH] shared_ptr::lock no longer requires exceptions. [SVN r44344] --- include/boost/detail/shared_count.hpp | 19 +++++++++++++++++++ include/boost/shared_ptr.hpp | 9 +++++++++ include/boost/weak_ptr.hpp | 26 +------------------------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/include/boost/detail/shared_count.hpp b/include/boost/detail/shared_count.hpp index 085b12f..1eae671 100644 --- a/include/boost/detail/shared_count.hpp +++ b/include/boost/detail/shared_count.hpp @@ -46,6 +46,8 @@ int const weak_count_id = 0x298C38A4; #endif +struct sp_nothrow_tag {}; + class weak_count; class shared_count @@ -216,6 +218,7 @@ public: } explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0 shared_count & operator= (shared_count const & r) // nothrow { @@ -248,6 +251,11 @@ public: return use_count() == 1; } + bool empty() const // nothrow + { + return pi_ == 0; + } + friend inline bool operator==(shared_count const & a, shared_count const & b) { return a.pi_ == b.pi_; @@ -364,6 +372,17 @@ inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ ) } } +inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ ) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if( pi_ != 0 && !pi_->add_ref_lock() ) + { + pi_ = 0; + } +} + } // namespace detail } // namespace boost diff --git a/include/boost/shared_ptr.hpp b/include/boost/shared_ptr.hpp index 1c0ad80..4b23ec1 100644 --- a/include/boost/shared_ptr.hpp +++ b/include/boost/shared_ptr.hpp @@ -220,6 +220,15 @@ public: px = r.px; } + template + shared_ptr( weak_ptr const & r, boost::detail::sp_nothrow_tag ): px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() ) // never throws + { + if( !pn.empty() ) + { + px = r.px; + } + } + template shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws { diff --git a/include/boost/weak_ptr.hpp b/include/boost/weak_ptr.hpp index ae606f2..4335738 100644 --- a/include/boost/weak_ptr.hpp +++ b/include/boost/weak_ptr.hpp @@ -93,31 +93,7 @@ public: shared_ptr lock() const // never throws { -#if defined(BOOST_HAS_THREADS) - - // optimization: avoid throw overhead - if(expired()) - { - return shared_ptr(); - } - - try - { - return shared_ptr(*this); - } - catch(bad_weak_ptr const &) - { - // Q: how can we get here? - // A: another thread may have invalidated r after the use_count test above. - return shared_ptr(); - } - -#else - - // optimization: avoid try/catch overhead when single threaded - return expired()? shared_ptr(): shared_ptr(*this); - -#endif + return shared_ptr( *this, boost::detail::sp_nothrow_tag() ); } long use_count() const // never throws