Imported Upstream version 0.8~alpha1
[platform/upstream/syncevolution.git] / src / 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 <memory> // boost.TR1 include order fix
17 #include <boost/detail/shared_count.hpp>
18 #include <boost/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     weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
65     {
66         px = r.lock().get();
67     }
68
69     template<class Y>
70     weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
71     {
72     }
73
74 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
75
76     template<class Y>
77     weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
78     {
79         px = r.lock().get();
80         pn = r.pn;
81         return *this;
82     }
83
84     template<class Y>
85     weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
86     {
87         px = r.px;
88         pn = r.pn;
89         return *this;
90     }
91
92 #endif
93
94     shared_ptr<T> lock() const // never throws
95     {
96 #if defined(BOOST_HAS_THREADS)
97
98         // optimization: avoid throw overhead
99         if(expired())
100         {
101             return shared_ptr<element_type>();
102         }
103
104         try
105         {
106             return shared_ptr<element_type>(*this);
107         }
108         catch(bad_weak_ptr const &)
109         {
110             // Q: how can we get here?
111             // A: another thread may have invalidated r after the use_count test above.
112             return shared_ptr<element_type>();
113         }
114
115 #else
116
117         // optimization: avoid try/catch overhead when single threaded
118         return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
119
120 #endif
121     }
122
123     long use_count() const // never throws
124     {
125         return pn.use_count();
126     }
127
128     bool expired() const // never throws
129     {
130         return pn.use_count() == 0;
131     }
132
133     void reset() // never throws in 1.30+
134     {
135         this_type().swap(*this);
136     }
137
138     void swap(this_type & other) // never throws
139     {
140         std::swap(px, other.px);
141         pn.swap(other.pn);
142     }
143
144     void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
145     {
146         px = px2;
147         pn = pn2;
148     }
149
150     template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
151     {
152         return pn < rhs.pn;
153     }
154
155 // Tasteless as this may seem, making all members public allows member templates
156 // to work in the absence of member template friends. (Matthew Langston)
157
158 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
159
160 private:
161
162     template<class Y> friend class weak_ptr;
163     template<class Y> friend class shared_ptr;
164
165 #endif
166
167     T * px;                       // contained pointer
168     boost::detail::weak_count pn; // reference counter
169
170 };  // weak_ptr
171
172 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
173 {
174     return a._internal_less(b);
175 }
176
177 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
178 {
179     a.swap(b);
180 }
181
182 // deprecated, provided for backward compatibility
183 template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
184 {
185     return r.lock();
186 }
187
188 } // namespace boost
189
190 #ifdef BOOST_MSVC
191 # pragma warning(pop)
192 #endif    
193
194 #endif  // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED