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