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
0006
0007
0008
0009
0010
0011
0012
0013
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
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
0040
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
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
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
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
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
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
0165 {
0166 return pn.empty();
0167 }
0168
0169 bool empty() const noexcept
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;
0216 boost::detail::weak_count pn;
0217
0218 };
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
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 }
0244
0245
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 }
0267
0268 #endif