]> git.lyx.org Git - lyx.git/blob - boost/boost/weak_ptr.hpp
Enable tex2lyx to run in-place.
[lyx.git] / boost / boost / weak_ptr.hpp
1 #ifndef BOOST_WEAK_PTR_HPP_INCLUDED
2 #define BOOST_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 <boost/shared_ptr.hpp>
17
18 #ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
19 # pragma warning(push)
20 # pragma warning(disable:4284) // odd return type for operator->
21 #endif
22
23 namespace boost
24 {
25
26 template<class T> class weak_ptr
27 {
28 private:
29
30     // Borland 5.5.1 specific workarounds
31     typedef weak_ptr<T> this_type;
32
33 public:
34
35     typedef T element_type;
36
37     weak_ptr(): px(0), pn() // never throws in 1.30+
38     {
39     }
40
41 //  generated copy constructor, assignment, destructor are fine
42
43
44 //
45 //  The "obvious" converting constructor implementation:
46 //
47 //  template<class Y>
48 //  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
49 //  {
50 //  }
51 //
52 //  has a serious problem.
53 //
54 //  r.px may already have been invalidated. The px(r.px)
55 //  conversion may require access to *r.px (virtual inheritance).
56 //
57 //  It is not possible to avoid spurious access violations since
58 //  in multithreaded programs r.px may be invalidated at any point.
59 //
60
61     template<class Y>
62     weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
63     {
64         px = r.lock().get();
65     }
66
67     template<class Y>
68     weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
69     {
70     }
71
72 #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
73
74     template<class Y>
75     weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
76     {
77         px = r.lock().get();
78         pn = r.pn;
79         return *this;
80     }
81
82     template<class Y>
83     weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
84     {
85         px = r.px;
86         pn = r.pn;
87         return *this;
88     }
89
90 #endif
91
92     shared_ptr<T> lock() const // never throws
93     {
94 #if defined(BOOST_HAS_THREADS)
95
96         // optimization: avoid throw overhead
97         if(expired())
98         {
99             return shared_ptr<element_type>();
100         }
101
102         try
103         {
104             return shared_ptr<element_type>(*this);
105         }
106         catch(bad_weak_ptr const &)
107         {
108             // Q: how can we get here?
109             // A: another thread may have invalidated r after the use_count test above.
110             return shared_ptr<element_type>();
111         }
112
113 #else
114
115         // optimization: avoid try/catch overhead when single threaded
116         return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
117
118 #endif
119     }
120
121     long use_count() const // never throws
122     {
123         return pn.use_count();
124     }
125
126     bool expired() const // never throws
127     {
128         return pn.use_count() == 0;
129     }
130
131     void reset() // never throws in 1.30+
132     {
133         this_type().swap(*this);
134     }
135
136     void swap(this_type & other) // never throws
137     {
138         std::swap(px, other.px);
139         pn.swap(other.pn);
140     }
141
142     void _internal_assign(T * px2, detail::shared_count const & pn2)
143     {
144         px = px2;
145         pn = pn2;
146     }
147
148     template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
149     {
150         return pn < rhs.pn;
151     }
152
153 // Tasteless as this may seem, making all members public allows member templates
154 // to work in the absence of member template friends. (Matthew Langston)
155
156 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
157
158 private:
159
160     template<class Y> friend class weak_ptr;
161     template<class Y> friend class shared_ptr;
162
163 #endif
164
165     T * px;                     // contained pointer
166     detail::weak_count pn;      // reference counter
167
168 };  // weak_ptr
169
170 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
171 {
172     return a._internal_less(b);
173 }
174
175 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
176 {
177     a.swap(b);
178 }
179
180 // deprecated, provided for backward compatibility
181 template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
182 {
183     return r.lock();
184 }
185
186 } // namespace boost
187
188 #ifdef BOOST_MSVC
189 # pragma warning(pop)
190 #endif    
191
192 #endif  // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED