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