X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=boost%2Fboost%2Fweak_ptr.hpp;h=d44b20127a1db354ba02ff529785953d8babb2ad;hb=5c3d9a254640468e40b2d30467a26222c91d856d;hp=c76cb28a13ebabca7b8dc703c238ae6fba60daf3;hpb=7cdb5279835b7ae9fe0fe0372f9fed7524f39da6;p=lyx.git diff --git a/boost/boost/weak_ptr.hpp b/boost/boost/weak_ptr.hpp index c76cb28a13..d44b20127a 100644 --- a/boost/boost/weak_ptr.hpp +++ b/boost/boost/weak_ptr.hpp @@ -4,7 +4,7 @@ // // weak_ptr.hpp // -// Copyright (c) 2001, 2002 Peter Dimov +// Copyright (c) 2001, 2002, 2003 Peter Dimov // // Permission to copy, use, modify, sell and distribute this software // is granted provided this copyright notice appears in all copies. @@ -24,7 +24,7 @@ namespace boost { -template class weak_ptr +template class weak_ptr { private: @@ -35,33 +35,52 @@ public: typedef T element_type; - weak_ptr(): px(0), pn() + weak_ptr(): px(0), pn() // never throws in 1.30+ { } // generated copy constructor, assignment, destructor are fine - template - weak_ptr(weak_ptr const & r): px(r.px), pn(r.pn) // never throws + +// +// The "obvious" converting constructor implementation: +// +// template +// weak_ptr(weak_ptr const & r): px(r.px), pn(r.pn) // never throws +// { +// } +// +// has a serious problem. +// +// r.px may already have been invalidated. The px(r.px) +// conversion may require access to *r.px (virtual inheritance). +// +// It is not possible to avoid spurious access violations since +// in multithreaded programs r.px may be invalidated at any point. +// + + template + weak_ptr(weak_ptr const & r): pn(r.pn) // never throws { + px = r.lock().get(); } - template + template weak_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws { } #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) - template + template weak_ptr & operator=(weak_ptr const & r) // never throws { - px = r.px; + px = r.lock().get(); pn = r.pn; return *this; } - template + template weak_ptr & operator=(shared_ptr const & r) // never throws { px = r.px; @@ -71,14 +90,33 @@ public: #endif - void reset() + shared_ptr lock() const // never throws { - this_type().swap(*this); - } +#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); - T * get() const // never throws; deprecated, removal pending, don't use - { - return pn.use_count() == 0? 0: px; +#endif } long use_count() const // never throws @@ -91,13 +129,24 @@ public: return pn.use_count() == 0; } + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + void swap(this_type & other) // never throws { std::swap(px, other.px); pn.swap(other.pn); } - bool less(this_type const & rhs) const // implementation detail, never throws + void _internal_assign(T * px2, detail::shared_count const & pn2) + { + px = px2; + pn = pn2; + } + + template bool _internal_less(weak_ptr const & rhs) const { return pn < rhs.pn; } @@ -109,8 +158,8 @@ public: private: - template friend class weak_ptr; - template friend class shared_ptr; + template friend class weak_ptr; + template friend class shared_ptr; #endif @@ -119,30 +168,9 @@ private: }; // weak_ptr -template inline bool operator==(weak_ptr const & a, weak_ptr const & b) +template inline bool operator<(weak_ptr const & a, weak_ptr const & b) { - return a.get() == b.get(); -} - -template inline bool operator!=(weak_ptr const & a, weak_ptr const & b) -{ - return a.get() != b.get(); -} - -#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 - -// Resolve the ambiguity between our op!= and the one in rel_ops - -template inline bool operator!=(weak_ptr const & a, weak_ptr const & b) -{ - return a.get() != b.get(); -} - -#endif - -template inline bool operator<(weak_ptr const & a, weak_ptr const & b) -{ - return a.less(b); + return a._internal_less(b); } template void swap(weak_ptr & a, weak_ptr & b) @@ -150,28 +178,12 @@ template void swap(weak_ptr & a, weak_ptr & b) a.swap(b); } -template shared_ptr make_shared(weak_ptr const & r) // never throws +// deprecated, provided for backward compatibility +template shared_ptr make_shared(weak_ptr const & r) { - // optimization: avoid throw overhead - if(r.use_count() == 0) - { - return shared_ptr(); - } - - try - { - return shared_ptr(r); - } - catch(use_count_is_zero const &) - { - return shared_ptr(); - } + return r.lock(); } -// Note: there is no get_pointer overload for weak_ptr. -// This is intentional. Even get() will disappear in a -// future release; these accessors are too error-prone. - } // namespace boost #ifdef BOOST_MSVC