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
0006
0007
0008
0009
0010
0011
0012
0013
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
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
0042
0043 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
0044
0045
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
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
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
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
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
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
0212 {
0213 return pn.empty();
0214 }
0215
0216 bool empty() const BOOST_SP_NOEXCEPT
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
0258
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;
0270 boost::detail::weak_count pn;
0271
0272 };
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
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 }
0298
0299
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
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 }
0325
0326 #endif