]> git.lyx.org Git - lyx.git/blob - boost/boost/smart_ptr/intrusive_ptr.hpp
Don't need this.
[lyx.git] / boost / boost / smart_ptr / intrusive_ptr.hpp
1 #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED\r
2 #define BOOST_SMART_PTR_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/smart_ptr/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(): px( 0 )\r
67     {\r
68     }\r
69 \r
70     intrusive_ptr( T * p, bool add_ref = true ): px( p )\r
71     {\r
72         if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );\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     : px( rhs.get() )\r
88     {\r
89         if( px != 0 ) intrusive_ptr_add_ref( px );\r
90     }\r
91 \r
92 #endif\r
93 \r
94     intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )\r
95     {\r
96         if( px != 0 ) intrusive_ptr_add_ref( px );\r
97     }\r
98 \r
99     ~intrusive_ptr()\r
100     {\r
101         if( px != 0 ) intrusive_ptr_release( px );\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 // Move support\r
115 \r
116 #if defined( BOOST_HAS_RVALUE_REFS )\r
117 \r
118     intrusive_ptr(intrusive_ptr && rhs): px( rhs.px )\r
119     {\r
120         rhs.px = 0;\r
121     }\r
122 \r
123     intrusive_ptr & operator=(intrusive_ptr && rhs)\r
124     {\r
125         this_type(std::move(rhs)).swap(*this);\r
126         return *this;\r
127     }\r
128 \r
129 #endif\r
130 \r
131     intrusive_ptr & operator=(intrusive_ptr const & rhs)\r
132     {\r
133         this_type(rhs).swap(*this);\r
134         return *this;\r
135     }\r
136 \r
137     intrusive_ptr & operator=(T * rhs)\r
138     {\r
139         this_type(rhs).swap(*this);\r
140         return *this;\r
141     }\r
142 \r
143     void reset()\r
144     {\r
145         this_type().swap( *this );\r
146     }\r
147 \r
148     void reset( T * rhs )\r
149     {\r
150         this_type( rhs ).swap( *this );\r
151     }\r
152 \r
153     T * get() const\r
154     {\r
155         return px;\r
156     }\r
157 \r
158     T & operator*() const\r
159     {\r
160         BOOST_ASSERT( px != 0 );\r
161         return *px;\r
162     }\r
163 \r
164     T * operator->() const\r
165     {\r
166         BOOST_ASSERT( px != 0 );\r
167         return px;\r
168     }\r
169 \r
170 // implicit conversion to "bool"\r
171 #include <boost/smart_ptr/detail/operator_bool.hpp>\r
172 \r
173     void swap(intrusive_ptr & rhs)\r
174     {\r
175         T * tmp = px;\r
176         px = rhs.px;\r
177         rhs.px = tmp;\r
178     }\r
179 \r
180 private:\r
181 \r
182     T * px;\r
183 };\r
184 \r
185 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)\r
186 {\r
187     return a.get() == b.get();\r
188 }\r
189 \r
190 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)\r
191 {\r
192     return a.get() != b.get();\r
193 }\r
194 \r
195 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)\r
196 {\r
197     return a.get() == b;\r
198 }\r
199 \r
200 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)\r
201 {\r
202     return a.get() != b;\r
203 }\r
204 \r
205 template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)\r
206 {\r
207     return a == b.get();\r
208 }\r
209 \r
210 template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)\r
211 {\r
212     return a != b.get();\r
213 }\r
214 \r
215 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96\r
216 \r
217 // Resolve the ambiguity between our op!= and the one in rel_ops\r
218 \r
219 template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)\r
220 {\r
221     return a.get() != b.get();\r
222 }\r
223 \r
224 #endif\r
225 \r
226 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)\r
227 {\r
228     return std::less<T *>()(a.get(), b.get());\r
229 }\r
230 \r
231 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)\r
232 {\r
233     lhs.swap(rhs);\r
234 }\r
235 \r
236 // mem_fn support\r
237 \r
238 template<class T> T * get_pointer(intrusive_ptr<T> const & p)\r
239 {\r
240     return p.get();\r
241 }\r
242 \r
243 template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)\r
244 {\r
245     return static_cast<T *>(p.get());\r
246 }\r
247 \r
248 template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)\r
249 {\r
250     return const_cast<T *>(p.get());\r
251 }\r
252 \r
253 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)\r
254 {\r
255     return dynamic_cast<T *>(p.get());\r
256 }\r
257 \r
258 // operator<<\r
259 \r
260 #if !defined(BOOST_NO_IOSTREAM)\r
261 \r
262 #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )\r
263 \r
264 template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)\r
265 {\r
266     os << p.get();\r
267     return os;\r
268 }\r
269 \r
270 #else\r
271 \r
272 // in STLport's no-iostreams mode no iostream symbols can be used\r
273 #ifndef _STLP_NO_IOSTREAMS\r
274 \r
275 # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)\r
276 // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL\r
277 using std::basic_ostream;\r
278 template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)\r
279 # else\r
280 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
281 # endif \r
282 {\r
283     os << p.get();\r
284     return os;\r
285 }\r
286 \r
287 #endif // _STLP_NO_IOSTREAMS\r
288 \r
289 #endif // __GNUC__ < 3\r
290 \r
291 #endif // !defined(BOOST_NO_IOSTREAM)\r
292 \r
293 } // namespace boost\r
294 \r
295 #ifdef BOOST_MSVC\r
296 # pragma warning(pop)\r
297 #endif    \r
298 \r
299 #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED\r