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