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