VirtualBox

source: vbox/trunk/src/libs/boost-1.37.0/boost/intrusive_ptr.hpp@ 24345

Last change on this file since 24345 was 16204, checked in by vboxsync, 16 years ago

export the boost stuff required for Main

File size: 6.6 KB
Line 
1#ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
2#define BOOST_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/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
38namespace 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
56template<class T> class intrusive_ptr
57{
58private:
59
60 typedef intrusive_ptr this_type;
61
62public:
63
64 typedef T element_type;
65
66 intrusive_ptr(): p_(0)
67 {
68 }
69
70 intrusive_ptr(T * p, bool add_ref = true): p_(p)
71 {
72 if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);
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 detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
81
82#else
83
84 intrusive_ptr( intrusive_ptr<U> const & rhs )
85
86#endif
87 : p_( rhs.get() )
88 {
89 if( p_ != 0 ) intrusive_ptr_add_ref( p_ );
90 }
91
92#endif
93
94 intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
95 {
96 if(p_ != 0) intrusive_ptr_add_ref(p_);
97 }
98
99 ~intrusive_ptr()
100 {
101 if(p_ != 0) intrusive_ptr_release(p_);
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 intrusive_ptr & operator=(intrusive_ptr const & rhs)
115 {
116 this_type(rhs).swap(*this);
117 return *this;
118 }
119
120 intrusive_ptr & operator=(T * rhs)
121 {
122 this_type(rhs).swap(*this);
123 return *this;
124 }
125
126 void reset()
127 {
128 this_type().swap( *this );
129 }
130
131 void reset( T * rhs )
132 {
133 this_type( rhs ).swap( *this );
134 }
135
136 T * get() const
137 {
138 return p_;
139 }
140
141 T & operator*() const
142 {
143 BOOST_ASSERT( p_ != 0 );
144 return *p_;
145 }
146
147 T * operator->() const
148 {
149 BOOST_ASSERT( p_ != 0 );
150 return p_;
151 }
152
153#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530)
154
155 operator bool () const
156 {
157 return p_ != 0;
158 }
159
160#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
161 typedef T * (this_type::*unspecified_bool_type)() const;
162
163 operator unspecified_bool_type() const // never throws
164 {
165 return p_ == 0? 0: &this_type::get;
166 }
167
168#else
169
170 typedef T * this_type::*unspecified_bool_type;
171
172 operator unspecified_bool_type () const
173 {
174 return p_ == 0? 0: &this_type::p_;
175 }
176
177#endif
178
179 // operator! is a Borland-specific workaround
180 bool operator! () const
181 {
182 return p_ == 0;
183 }
184
185 void swap(intrusive_ptr & rhs)
186 {
187 T * tmp = p_;
188 p_ = rhs.p_;
189 rhs.p_ = tmp;
190 }
191
192private:
193
194 T * p_;
195};
196
197template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
198{
199 return a.get() == b.get();
200}
201
202template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
203{
204 return a.get() != b.get();
205}
206
207template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
208{
209 return a.get() == b;
210}
211
212template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
213{
214 return a.get() != b;
215}
216
217template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
218{
219 return a == b.get();
220}
221
222template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
223{
224 return a != b.get();
225}
226
227#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
228
229// Resolve the ambiguity between our op!= and the one in rel_ops
230
231template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
232{
233 return a.get() != b.get();
234}
235
236#endif
237
238template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
239{
240 return std::less<T *>()(a.get(), b.get());
241}
242
243template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
244{
245 lhs.swap(rhs);
246}
247
248// mem_fn support
249
250template<class T> T * get_pointer(intrusive_ptr<T> const & p)
251{
252 return p.get();
253}
254
255template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
256{
257 return static_cast<T *>(p.get());
258}
259
260template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
261{
262 return const_cast<T *>(p.get());
263}
264
265template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
266{
267 return dynamic_cast<T *>(p.get());
268}
269
270// operator<<
271
272#if !defined(BOOST_NO_IOSTREAM)
273
274#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) )
275
276template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
277{
278 os << p.get();
279 return os;
280}
281
282#else
283
284// in STLport's no-iostreams mode no iostream symbols can be used
285#ifndef _STLP_NO_IOSTREAMS
286
287# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
288// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
289using std::basic_ostream;
290template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
291# else
292template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
293# endif
294{
295 os << p.get();
296 return os;
297}
298
299#endif // _STLP_NO_IOSTREAMS
300
301#endif // __GNUC__ < 3
302
303#endif // !defined(BOOST_NO_IOSTREAM)
304
305} // namespace boost
306
307#ifdef BOOST_MSVC
308# pragma warning(pop)
309#endif
310
311#endif // #ifndef BOOST_INTRUSIVE_PTR_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette