Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:50:38

0001 #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
0003 
0004 //
0005 //  weak_ptr.hpp
0006 //
0007 //  Copyright (c) 2001, 2002, 2003 Peter Dimov
0008 //
0009 //  Distributed under the Boost Software License, Version 1.0. (See
0010 //  accompanying file LICENSE_1_0.txt or copy at
0011 //  http://www.boost.org/LICENSE_1_0.txt)
0012 //
0013 //  See http://www.boost.org/libs/smart_ptr/ for documentation.
0014 //
0015 
0016 #include <boost/smart_ptr/detail/shared_count.hpp>
0017 #include <boost/smart_ptr/shared_ptr.hpp>
0018 #include <memory>
0019 #include <cstddef>
0020 
0021 namespace boost
0022 {
0023 
0024 template<class T> class weak_ptr
0025 {
0026 private:
0027 
0028     // Borland 5.5.1 specific workarounds
0029     typedef weak_ptr<T> this_type;
0030 
0031 public:
0032 
0033     typedef typename boost::detail::sp_element< T >::type element_type;
0034 
0035     constexpr weak_ptr() noexcept : px(0), pn()
0036     {
0037     }
0038 
0039 //  generated copy constructor, assignment, destructor are fine...
0040 // ... except in C++0x, move disables the implicit copy
0041 
0042     weak_ptr( weak_ptr const & r ) noexcept : px( r.px ), pn( r.pn )
0043     {
0044     }
0045 
0046     weak_ptr & operator=( weak_ptr const & r ) noexcept
0047     {
0048         px = r.px;
0049         pn = r.pn;
0050         return *this;
0051     }
0052 
0053 //
0054 //  The "obvious" converting constructor implementation:
0055 //
0056 //  template<class Y>
0057 //  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn)
0058 //  {
0059 //  }
0060 //
0061 //  has a serious problem.
0062 //
0063 //  r.px may already have been invalidated. The px(r.px)
0064 //  conversion may require access to *r.px (virtual inheritance).
0065 //
0066 //  It is not possible to avoid spurious access violations since
0067 //  in multithreaded programs r.px may be invalidated at any point.
0068 //
0069 
0070     template<class Y>
0071     weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0072     noexcept : px(r.lock().get()), pn(r.pn)
0073     {
0074         boost::detail::sp_assert_convertible< Y, T >();
0075     }
0076 
0077     template<class Y>
0078     weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0079     noexcept : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
0080     {
0081         boost::detail::sp_assert_convertible< Y, T >();
0082         r.px = 0;
0083     }
0084 
0085     // for better efficiency in the T == Y case
0086     weak_ptr( weak_ptr && r )
0087     noexcept : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
0088     {
0089         r.px = 0;
0090     }
0091 
0092     // for better efficiency in the T == Y case
0093     weak_ptr & operator=( weak_ptr && r ) noexcept
0094     {
0095         this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
0096         return *this;
0097     }
0098 
0099 
0100     template<class Y>
0101     weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0102     noexcept : px( r.px ), pn( r.pn )
0103     {
0104         boost::detail::sp_assert_convertible< Y, T >();
0105     }
0106 
0107     // aliasing
0108     template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) noexcept: px( p ), pn( r.pn )
0109     {
0110     }
0111 
0112     template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) noexcept: px( p ), pn( r.pn )
0113     {
0114     }
0115 
0116     template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) noexcept: px( p ), pn( std::move( r.pn ) )
0117     {
0118     }
0119 
0120     template<class Y>
0121     weak_ptr & operator=( weak_ptr<Y> const & r ) noexcept
0122     {
0123         boost::detail::sp_assert_convertible< Y, T >();
0124 
0125         px = r.lock().get();
0126         pn = r.pn;
0127 
0128         return *this;
0129     }
0130 
0131     template<class Y>
0132     weak_ptr & operator=( weak_ptr<Y> && r ) noexcept
0133     {
0134         this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
0135         return *this;
0136     }
0137 
0138     template<class Y>
0139     weak_ptr & operator=( shared_ptr<Y> const & r ) noexcept
0140     {
0141         boost::detail::sp_assert_convertible< Y, T >();
0142 
0143         px = r.px;
0144         pn = r.pn;
0145 
0146         return *this;
0147     }
0148 
0149     shared_ptr<T> lock() const noexcept
0150     {
0151         return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
0152     }
0153 
0154     long use_count() const noexcept
0155     {
0156         return pn.use_count();
0157     }
0158 
0159     bool expired() const noexcept
0160     {
0161         return pn.use_count() == 0;
0162     }
0163 
0164     bool _empty() const noexcept // extension, not in std::weak_ptr
0165     {
0166         return pn.empty();
0167     }
0168 
0169     bool empty() const noexcept // extension, not in std::weak_ptr
0170     {
0171         return pn.empty();
0172     }
0173 
0174     void reset() noexcept
0175     {
0176         this_type().swap(*this);
0177     }
0178 
0179     void swap(this_type & other) noexcept
0180     {
0181         std::swap(px, other.px);
0182         pn.swap(other.pn);
0183     }
0184 
0185     template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const noexcept
0186     {
0187         return pn < rhs.pn;
0188     }
0189 
0190     template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const noexcept
0191     {
0192         return pn < rhs.pn;
0193     }
0194 
0195     template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const noexcept
0196     {
0197         return pn == rhs.pn;
0198     }
0199 
0200     template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const noexcept
0201     {
0202         return pn == rhs.pn;
0203     }
0204 
0205     std::size_t owner_hash_value() const noexcept
0206     {
0207         return pn.hash_value();
0208     }
0209 
0210 private:
0211 
0212     template<class Y> friend class weak_ptr;
0213     template<class Y> friend class shared_ptr;
0214 
0215     element_type * px;            // contained pointer
0216     boost::detail::weak_count pn; // reference counter
0217 
0218 };  // weak_ptr
0219 
0220 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) noexcept
0221 {
0222     return a.owner_before( b );
0223 }
0224 
0225 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) noexcept
0226 {
0227     a.swap(b);
0228 }
0229 
0230 #if defined(__cpp_deduction_guides)
0231 
0232 template<class T> weak_ptr( shared_ptr<T> ) -> weak_ptr<T>;
0233 
0234 #endif
0235 
0236 // hash_value
0237 
0238 template< class T > std::size_t hash_value( boost::weak_ptr<T> const & p ) noexcept
0239 {
0240     return p.owner_hash_value();
0241 }
0242 
0243 } // namespace boost
0244 
0245 // std::hash, std::equal_to
0246 
0247 namespace std
0248 {
0249 
0250 template<class T> struct hash< ::boost::weak_ptr<T> >
0251 {
0252     std::size_t operator()( ::boost::weak_ptr<T> const & p ) const noexcept
0253     {
0254         return p.owner_hash_value();
0255     }
0256 };
0257 
0258 template<class T> struct equal_to< ::boost::weak_ptr<T> >
0259 {
0260     bool operator()( ::boost::weak_ptr<T> const & a, ::boost::weak_ptr<T> const & b ) const noexcept
0261     {
0262         return a.owner_equals( b );
0263     }
0264 };
0265 
0266 } // namespace std
0267 
0268 #endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED