]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/smart_ptr/weak_ptr.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / 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 } // namespace boost
268
269 #endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED