source: XIOS/dev/dev_olga/src/extern/boost/include/boost/smart_ptr/intrusive_ptr.hpp @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 6.3 KB
Line 
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
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(): 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
180private:
181
182    T * px;
183};
184
185template<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
190template<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
195template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
196{
197    return a.get() == b;
198}
199
200template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
201{
202    return a.get() != b;
203}
204
205template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
206{
207    return a == b.get();
208}
209
210template<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
219template<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
226template<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
231template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
232{
233    lhs.swap(rhs);
234}
235
236// mem_fn support
237
238template<class T> T * get_pointer(intrusive_ptr<T> const & p)
239{
240    return p.get();
241}
242
243template<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
248template<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
253template<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
264template<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
277using std::basic_ostream;
278template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
279# else
280template<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
Note: See TracBrowser for help on using the repository browser.