]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/weak_ptr.hpp
07ba189f4ca8147ff561edfa877b69fb753aa8b5
[ceph.git] / ceph / src / boost / boost / smart_ptr / weak_ptr.hpp
1 #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
2 #define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
3
4 //
5 // weak_ptr.hpp
6 //
7 // Copyright (c) 2001, 2002, 2003 Peter Dimov
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 //
13 // See http://www.boost.org/libs/smart_ptr/ for documentation.
14 //
15
16 #include <memory> // boost.TR1 include order fix
17 #include <boost/smart_ptr/detail/shared_count.hpp>
18 #include <boost/smart_ptr/shared_ptr.hpp>
19 #include <boost/smart_ptr/detail/sp_noexcept.hpp>
20
21 namespace boost
22 {
23
24 template<class T> class weak_ptr
25 {
26 private:
27
28 // Borland 5.5.1 specific workarounds
29 typedef weak_ptr<T> this_type;
30
31 public:
32
33 typedef typename boost::detail::sp_element< T >::type element_type;
34
35 BOOST_CONSTEXPR weak_ptr() BOOST_SP_NOEXCEPT : px(0), pn()
36 {
37 }
38
39 // generated copy constructor, assignment, destructor are fine...
40
41 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
42
43 // ... except in C++0x, move disables the implicit copy
44
45 weak_ptr( weak_ptr const & r ) BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
46 {
47 }
48
49 weak_ptr & operator=( weak_ptr const & r ) BOOST_SP_NOEXCEPT
50 {
51 px = r.px;
52 pn = r.pn;
53 return *this;
54 }
55
56 #endif
57
58 //
59 // The "obvious" converting constructor implementation:
60 //
61 // template<class Y>
62 // weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn)
63 // {
64 // }
65 //
66 // has a serious problem.
67 //
68 // r.px may already have been invalidated. The px(r.px)
69 // conversion may require access to *r.px (virtual inheritance).
70 //
71 // It is not possible to avoid spurious access violations since
72 // in multithreaded programs r.px may be invalidated at any point.
73 //
74
75 template<class Y>
76 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
77
78 weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
79
80 #else
81
82 weak_ptr( weak_ptr<Y> const & r )
83
84 #endif
85 BOOST_SP_NOEXCEPT : px(r.lock().get()), pn(r.pn)
86 {
87 boost::detail::sp_assert_convertible< Y, T >();
88 }
89
90 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
91
92 template<class Y>
93 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
94
95 weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
96
97 #else
98
99 weak_ptr( weak_ptr<Y> && r )
100
101 #endif
102 BOOST_SP_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
103 {
104 boost::detail::sp_assert_convertible< Y, T >();
105 r.px = 0;
106 }
107
108 // for better efficiency in the T == Y case
109 weak_ptr( weak_ptr && r )
110 BOOST_SP_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
111 {
112 r.px = 0;
113 }
114
115 // for better efficiency in the T == Y case
116 weak_ptr & operator=( weak_ptr && r ) BOOST_SP_NOEXCEPT
117 {
118 this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
119 return *this;
120 }
121
122
123 #endif
124
125 template<class Y>
126 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
127
128 weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
129
130 #else
131
132 weak_ptr( shared_ptr<Y> const & r )
133
134 #endif
135 BOOST_SP_NOEXCEPT : px( r.px ), pn( r.pn )
136 {
137 boost::detail::sp_assert_convertible< Y, T >();
138 }
139
140 // aliasing
141 template<class Y> weak_ptr(shared_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( r.pn )
142 {
143 }
144
145 template<class Y> weak_ptr(weak_ptr<Y> const & r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( r.pn )
146 {
147 }
148
149 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
150
151 template<class Y> weak_ptr(weak_ptr<Y> && r, element_type * p) BOOST_SP_NOEXCEPT: px( p ), pn( std::move( r.pn ) )
152 {
153 }
154
155 #endif
156
157 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
158
159 template<class Y>
160 weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
161 {
162 boost::detail::sp_assert_convertible< Y, T >();
163
164 px = r.lock().get();
165 pn = r.pn;
166
167 return *this;
168 }
169
170 #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
171
172 template<class Y>
173 weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_SP_NOEXCEPT
174 {
175 this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
176 return *this;
177 }
178
179 #endif
180
181 template<class Y>
182 weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
183 {
184 boost::detail::sp_assert_convertible< Y, T >();
185
186 px = r.px;
187 pn = r.pn;
188
189 return *this;
190 }
191
192 #endif
193
194 shared_ptr<T> lock() const BOOST_SP_NOEXCEPT
195 {
196 return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
197 }
198
199 long use_count() const BOOST_SP_NOEXCEPT
200 {
201 return pn.use_count();
202 }
203
204 bool expired() const BOOST_SP_NOEXCEPT
205 {
206 return pn.use_count() == 0;
207 }
208
209 bool _empty() const BOOST_SP_NOEXCEPT // extension, not in std::weak_ptr
210 {
211 return pn.empty();
212 }
213
214 bool empty() const BOOST_SP_NOEXCEPT // extension, not in std::weak_ptr
215 {
216 return pn.empty();
217 }
218
219 void reset() BOOST_SP_NOEXCEPT
220 {
221 this_type().swap(*this);
222 }
223
224 void swap(this_type & other) BOOST_SP_NOEXCEPT
225 {
226 std::swap(px, other.px);
227 pn.swap(other.pn);
228 }
229
230 template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
231 {
232 return pn < rhs.pn;
233 }
234
235 template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_SP_NOEXCEPT
236 {
237 return pn < rhs.pn;
238 }
239
240 // Tasteless as this may seem, making all members public allows member templates
241 // to work in the absence of member template friends. (Matthew Langston)
242
243 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
244
245 private:
246
247 template<class Y> friend class weak_ptr;
248 template<class Y> friend class shared_ptr;
249
250 #endif
251
252 element_type * px; // contained pointer
253 boost::detail::weak_count pn; // reference counter
254
255 }; // weak_ptr
256
257 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_SP_NOEXCEPT
258 {
259 return a.owner_before( b );
260 }
261
262 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_SP_NOEXCEPT
263 {
264 a.swap(b);
265 }
266
267 #if defined(__cpp_deduction_guides)
268
269 template<class T> weak_ptr( shared_ptr<T> ) -> weak_ptr<T>;
270
271 #endif
272
273 } // namespace boost
274
275 #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED