Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:31:10

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/requires_cxx11.hpp>
0017 #include <boost/smart_ptr/detail/shared_count.hpp>
0018 #include <boost/smart_ptr/shared_ptr.hpp>
0019 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
0020 #include <memory>
0021 #include <cstddef>
0022 
0023 namespace boost
0024 {
0025 
0026 template<class T> class weak_ptr
0027 {
0028 private:
0029 
0030     // Borland 5.5.1 specific workarounds
0031     typedef weak_ptr<T> this_type;
0032 
0033 public:
0034 
0035     typedef typename boost::detail::sp_element< T >::type element_type;
0036 
0037     BOOST_CONSTEXPR weak_ptr() BOOST_SP_NOEXCEPT : px(0), pn()
0038     {
0039     }
0040 
0041 //  generated copy constructor, assignment, destructor are fine...
0042 
0043 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
0044 
0045 // ... except in C++0x, move disables the implicit copy
0046 
0047     weak_ptr( weak_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
0048     {
0049     }
0050 
0051     weak_ptr & operator=( weak_ptr const & r ) BOOST_SP_NOEXCEPT
0052     {
0053         px = r.px;
0054         pn = r.pn;
0055         return *this;
0056     }
0057 
0058 #endif
0059 
0060 //
0061 //  The "obvious" converting constructor implementation:
0062 //
0063 //  template<class Y>
0064 //  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn)
0065 //  {
0066 //  }
0067 //
0068 //  has a serious problem.
0069 //
0070 //  r.px may already have been invalidated. The px(r.px)
0071 //  conversion may require access to *r.px (virtual inheritance).
0072 //
0073 //  It is not possible to avoid spurious access violations since
0074 //  in multithreaded programs r.px may be invalidated at any point.
0075 //
0076 
0077     template<class Y>
0078 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
0079 
0080     weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0081 
0082 #else
0083 
0084     weak_ptr( weak_ptr<Y> const & r )
0085 
0086 #endif
0087     BOOST_SP_NOEXCEPT : px(r.lock().get()), pn(r.pn)
0088     {
0089         boost::detail::sp_assert_convertible< Y, T >();
0090     }
0091 
0092 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
0093 
0094     template<class Y>
0095 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
0096 
0097     weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0098 
0099 #else
0100 
0101     weak_ptr( weak_ptr<Y> && r )
0102 
0103 #endif
0104     BOOST_SP_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
0105     {
0106         boost::detail::sp_assert_convertible< Y, T >();
0107         r.px = 0;
0108     }
0109 
0110     // for better efficiency in the T == Y case
0111     weak_ptr( weak_ptr && r )
0112     BOOST_SP_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
0113     {
0114         r.px = 0;
0115     }
0116 
0117     // for better efficiency in the T == Y case
0118     weak_ptr & operator=( weak_ptr && r ) BOOST_SP_NOEXCEPT
0119     {
0120         this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
0121         return *this;
0122     }
0123 
0124 
0125 #endif
0126 
0127     template<class Y>
0128 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
0129 
0130     weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
0131 
0132 #else
0133 
0134     weak_ptr( shared_ptr<Y> const & r )
0135 
0136 #endif
0137     BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
0138     {
0139         boost::detail::sp_assert_convertible< Y, T >();
0140     }
0141 
0142     // aliasing
0143     template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( r.pn )
0144     {
0145     }
0146 
0147     template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( r.pn )
0148     {
0149     }
0150 
0151 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
0152 
0153     template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( std::move( r.pn ) )
0154     {
0155     }
0156 
0157 #endif
0158 
0159 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
0160 
0161     template<class Y>
0162     weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
0163     {
0164         boost::detail::sp_assert_convertible< Y, T >();
0165 
0166         px = r.lock().get();
0167         pn = r.pn;
0168 
0169         return *this;
0170     }
0171 
0172 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
0173 
0174     template<class Y>
0175     weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_SP_NOEXCEPT
0176     {
0177         this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
0178         return *this;
0179     }
0180 
0181 #endif
0182 
0183     template<class Y>
0184     weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
0185     {
0186         boost::detail::sp_assert_convertible< Y, T >();
0187 
0188         px = r.px;
0189         pn = r.pn;
0190 
0191         return *this;
0192     }
0193 
0194 #endif
0195 
0196     shared_ptr<T> lock() const BOOST_SP_NOEXCEPT
0197     {
0198         return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
0199     }
0200 
0201     long use_count() const BOOST_SP_NOEXCEPT
0202     {
0203         return pn.use_count();
0204     }
0205 
0206     bool expired() const BOOST_SP_NOEXCEPT
0207     {
0208         return pn.use_count() == 0;
0209     }
0210 
0211     bool _empty() const BOOST_SP_NOEXCEPT // extension, not in std::weak_ptr
0212     {
0213         return pn.empty();
0214     }
0215 
0216     bool empty() const BOOST_SP_NOEXCEPT // extension, not in std::weak_ptr
0217     {
0218         return pn.empty();
0219     }
0220 
0221     void reset() BOOST_SP_NOEXCEPT
0222     {
0223         this_type().swap(*this);
0224     }
0225 
0226     void swap(this_type & other) BOOST_SP_NOEXCEPT
0227     {
0228         std::swap(px, other.px);
0229         pn.swap(other.pn);
0230     }
0231 
0232     template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
0233     {
0234         return pn < rhs.pn;
0235     }
0236 
0237     template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
0238     {
0239         return pn < rhs.pn;
0240     }
0241 
0242     template<class Y> bool owner_equals( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
0243     {
0244         return pn == rhs.pn;
0245     }
0246 
0247     template<class Y> bool owner_equals( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
0248     {
0249         return pn == rhs.pn;
0250     }
0251 
0252     std::size_t owner_hash_value() const BOOST_SP_NOEXCEPT
0253     {
0254         return pn.hash_value();
0255     }
0256 
0257 // Tasteless as this may seem, making all members public allows member templates
0258 // to work in the absence of member template friends. (Matthew Langston)
0259 
0260 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
0261 
0262 private:
0263 
0264     template<class Y> friend class weak_ptr;
0265     template<class Y> friend class shared_ptr;
0266 
0267 #endif
0268 
0269     element_type * px;            // contained pointer
0270     boost::detail::weak_count pn; // reference counter
0271 
0272 };  // weak_ptr
0273 
0274 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_SP_NOEXCEPT
0275 {
0276     return a.owner_before( b );
0277 }
0278 
0279 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_SP_NOEXCEPT
0280 {
0281     a.swap(b);
0282 }
0283 
0284 #if defined(__cpp_deduction_guides)
0285 
0286 template<class T> weak_ptr( shared_ptr<T> ) -> weak_ptr<T>;
0287 
0288 #endif
0289 
0290 // hash_value
0291 
0292 template< class T > std::size_t hash_value( boost::weak_ptr<T> const & p ) BOOST_SP_NOEXCEPT
0293 {
0294     return p.owner_hash_value();
0295 }
0296 
0297 } // namespace boost
0298 
0299 // std::hash, std::equal_to
0300 
0301 namespace std
0302 {
0303 
0304 #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
0305 
0306 template<class T> struct hash< ::boost::weak_ptr<T> >
0307 {
0308     std::size_t operator()( ::boost::weak_ptr<T> const & p ) const BOOST_SP_NOEXCEPT
0309     {
0310         return p.owner_hash_value();
0311     }
0312 };
0313 
0314 #endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
0315 
0316 template<class T> struct equal_to< ::boost::weak_ptr<T> >
0317 {
0318     bool operator()( ::boost::weak_ptr<T> const & a, ::boost::weak_ptr<T> const & b ) const BOOST_SP_NOEXCEPT
0319     {
0320         return a.owner_equals( b );
0321     }
0322 };
0323 
0324 } // namespace std
0325 
0326 #endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED