Fixes for VS 2008
[dyninst.git] / external / boost / intrusive_ptr.hpp
1 #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED\r
2 #define BOOST_INTRUSIVE_PTR_HPP_INCLUDED\r
3 \r
4 //\r
5 //  intrusive_ptr.hpp\r
6 //\r
7 //  Copyright (c) 2001, 2002 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/intrusive_ptr.html for documentation.\r
14 //\r
15 \r
16 #include <boost/config.hpp>\r
17 \r
18 #ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash\r
19 # pragma warning(push)\r
20 # pragma warning(disable:4284) // odd return type for operator->\r
21 #endif\r
22 \r
23 #include <boost/assert.hpp>\r
24 #include <boost/detail/workaround.hpp>\r
25 #include <boost/detail/sp_convertible.hpp>\r
26 \r
27 #include <boost/config/no_tr1/functional.hpp>           // for std::less\r
28 \r
29 #if !defined(BOOST_NO_IOSTREAM)\r
30 #if !defined(BOOST_NO_IOSFWD)\r
31 #include <iosfwd>               // for std::basic_ostream\r
32 #else\r
33 #include <ostream>\r
34 #endif\r
35 #endif\r
36 \r
37 \r
38 namespace boost\r
39 {\r
40 \r
41 //\r
42 //  intrusive_ptr\r
43 //\r
44 //  A smart pointer that uses intrusive reference counting.\r
45 //\r
46 //  Relies on unqualified calls to\r
47 //  \r
48 //      void intrusive_ptr_add_ref(T * p);\r
49 //      void intrusive_ptr_release(T * p);\r
50 //\r
51 //          (p != 0)\r
52 //\r
53 //  The object is responsible for destroying itself.\r
54 //\r
55 \r
56 template<class T> class intrusive_ptr\r
57 {\r
58 private:\r
59 \r
60     typedef intrusive_ptr this_type;\r
61 \r
62 public:\r
63 \r
64     typedef T element_type;\r
65 \r
66     intrusive_ptr(): p_(0)\r
67     {\r
68     }\r
69 \r
70     intrusive_ptr(T * p, bool add_ref = true): p_(p)\r
71     {\r
72         if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);\r
73     }\r
74 \r
75 #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)\r
76 \r
77     template<class U>\r
78 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )\r
79 \r
80     intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )\r
81 \r
82 #else\r
83 \r
84     intrusive_ptr( intrusive_ptr<U> const & rhs )\r
85 \r
86 #endif\r
87     : p_( rhs.get() )\r
88     {\r
89         if( p_ != 0 ) intrusive_ptr_add_ref( p_ );\r
90     }\r
91 \r
92 #endif\r
93 \r
94     intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)\r
95     {\r
96         if(p_ != 0) intrusive_ptr_add_ref(p_);\r
97     }\r
98 \r
99     ~intrusive_ptr()\r
100     {\r
101         if(p_ != 0) intrusive_ptr_release(p_);\r
102     }\r
103 \r
104 #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)\r
105 \r
106     template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)\r
107     {\r
108         this_type(rhs).swap(*this);\r
109         return *this;\r
110     }\r
111 \r
112 #endif\r
113 \r
114     intrusive_ptr & operator=(intrusive_ptr const & rhs)\r
115     {\r
116         this_type(rhs).swap(*this);\r
117         return *this;\r
118     }\r
119 \r
120     intrusive_ptr & operator=(T * rhs)\r
121     {\r
122         this_type(rhs).swap(*this);\r
123         return *this;\r
124     }\r
125 \r
126     void reset()\r
127     {\r
128         this_type().swap( *this );\r
129     }\r
130 \r
131     void reset( T * rhs )\r
132     {\r
133         this_type( rhs ).swap( *this );\r
134     }\r
135 \r
136     T * get() const\r
137     {\r
138         return p_;\r
139     }\r
140 \r
141     T & operator*() const\r
142     {\r
143         BOOST_ASSERT( p_ != 0 );\r
144         return *p_;\r
145     }\r
146 \r
147     T * operator->() const\r
148     {\r
149         BOOST_ASSERT( p_ != 0 );\r
150         return p_;\r
151     }\r
152 \r
153 #if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)\r
154 \r
155     operator bool () const\r
156     {\r
157         return p_ != 0;\r
158     }\r
159 \r
160 #elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))\r
161     typedef T * (this_type::*unspecified_bool_type)() const;\r
162     \r
163     operator unspecified_bool_type() const // never throws\r
164     {\r
165         return p_ == 0? 0: &this_type::get;\r
166     }\r
167 \r
168 #else \r
169 \r
170     typedef T * this_type::*unspecified_bool_type;\r
171 \r
172     operator unspecified_bool_type () const\r
173     {\r
174         return p_ == 0? 0: &this_type::p_;\r
175     }\r
176 \r
177 #endif\r
178 \r
179     // operator! is a Borland-specific workaround\r
180     bool operator! () const\r
181     {\r
182         return p_ == 0;\r
183     }\r
184 \r
185     void swap(intrusive_ptr & rhs)\r
186     {\r
187         T * tmp = p_;\r
188         p_ = rhs.p_;\r
189         rhs.p_ = tmp;\r
190     }\r
191 \r
192 private:\r
193 \r
194     T * p_;\r
195 };\r
196 \r
197 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)\r
198 {\r
199     return a.get() == b.get();\r
200 }\r
201 \r
202 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)\r
203 {\r
204     return a.get() != b.get();\r
205 }\r
206 \r
207 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)\r
208 {\r
209     return a.get() == b;\r
210 }\r
211 \r
212 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)\r
213 {\r
214     return a.get() != b;\r
215 }\r
216 \r
217 template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)\r
218 {\r
219     return a == b.get();\r
220 }\r
221 \r
222 template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)\r
223 {\r
224     return a != b.get();\r
225 }\r
226 \r
227 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96\r
228 \r
229 // Resolve the ambiguity between our op!= and the one in rel_ops\r
230 \r
231 template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)\r
232 {\r
233     return a.get() != b.get();\r
234 }\r
235 \r
236 #endif\r
237 \r
238 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)\r
239 {\r
240     return std::less<T *>()(a.get(), b.get());\r
241 }\r
242 \r
243 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)\r
244 {\r
245     lhs.swap(rhs);\r
246 }\r
247 \r
248 // mem_fn support\r
249 \r
250 template<class T> T * get_pointer(intrusive_ptr<T> const & p)\r
251 {\r
252     return p.get();\r
253 }\r
254 \r
255 template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)\r
256 {\r
257     return static_cast<T *>(p.get());\r
258 }\r
259 \r
260 template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)\r
261 {\r
262     return const_cast<T *>(p.get());\r
263 }\r
264 \r
265 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)\r
266 {\r
267     return dynamic_cast<T *>(p.get());\r
268 }\r
269 \r
270 // operator<<\r
271 \r
272 #if !defined(BOOST_NO_IOSTREAM)\r
273 \r
274 #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )\r
275 \r
276 template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)\r
277 {\r
278     os << p.get();\r
279     return os;\r
280 }\r
281 \r
282 #else\r
283 \r
284 // in STLport's no-iostreams mode no iostream symbols can be used\r
285 #ifndef _STLP_NO_IOSTREAMS\r
286 \r
287 # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)\r
288 // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL\r
289 using std::basic_ostream;\r
290 template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)\r
291 # else\r
292 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)\r
293 # endif \r
294 {\r
295     os << p.get();\r
296     return os;\r
297 }\r
298 \r
299 #endif // _STLP_NO_IOSTREAMS\r
300 \r
301 #endif // __GNUC__ < 3\r
302 \r
303 #endif // !defined(BOOST_NO_IOSTREAM)\r
304 \r
305 } // namespace boost\r
306 \r
307 #ifdef BOOST_MSVC\r
308 # pragma warning(pop)\r
309 #endif    \r
310 \r
311 #endif  // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED\r