Line data Source code
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 0 : 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 0 : 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 0 : weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_SP_NOEXCEPT
183 : {
184 : boost::detail::sp_assert_convertible< Y, T >();
185 :
186 0 : px = r.px;
187 0 : pn = r.pn;
188 :
189 : return *this;
190 : }
191 :
192 : #endif
193 :
194 0 : shared_ptr<T> lock() const BOOST_SP_NOEXCEPT
195 : {
196 0 : 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 0 : bool expired() const BOOST_SP_NOEXCEPT
205 : {
206 0 : 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 : } // namespace boost
268 :
269 : #endif // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
|