intrusive_ptr.hpp
Go to the documentation of this file.
00001 #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
00002 #define BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED
00003 
00004 //
00005 //  intrusive_ptr.hpp
00006 //
00007 //  Copyright (c) 2001, 2002 Peter Dimov
00008 //
00009 // Distributed under the Boost Software License, Version 1.0. (See
00010 // accompanying file LICENSE_1_0.txt or copy at
00011 // http://www.boost.org/LICENSE_1_0.txt)
00012 //
00013 //  See http://www.boost.org/libs/smart_ptr/intrusive_ptr.html for documentation.
00014 //
00015 
00016 #include <boost/config.hpp>
00017 
00018 #ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
00019 # pragma warning(push)
00020 # pragma warning(disable:4284) // odd return type for operator->
00021 #endif
00022 
00023 #include <boost/assert.hpp>
00024 #include <boost/detail/workaround.hpp>
00025 #include <boost/smart_ptr/detail/sp_convertible.hpp>
00026 
00027 #include <boost/config/no_tr1/functional.hpp>           // for std::less
00028 
00029 #if !defined(BOOST_NO_IOSTREAM)
00030 #if !defined(BOOST_NO_IOSFWD)
00031 #include <iosfwd>               // for std::basic_ostream
00032 #else
00033 #include <ostream>
00034 #endif
00035 #endif
00036 
00037 
00038 namespace boost
00039 {
00040 
00041 //
00042 //  intrusive_ptr
00043 //
00044 //  A smart pointer that uses intrusive reference counting.
00045 //
00046 //  Relies on unqualified calls to
00047 //  
00048 //      void intrusive_ptr_add_ref(T * p);
00049 //      void intrusive_ptr_release(T * p);
00050 //
00051 //          (p != 0)
00052 //
00053 //  The object is responsible for destroying itself.
00054 //
00055 
00056 template<class T> class intrusive_ptr
00057 {
00058 private:
00059 
00060     typedef intrusive_ptr this_type;
00061 
00062 public:
00063 
00064     typedef T element_type;
00065 
00066     intrusive_ptr(): px( 0 )
00067     {
00068     }
00069 
00070     intrusive_ptr( T * p, bool add_ref = true ): px( p )
00071     {
00072         if( px != 0 && add_ref ) intrusive_ptr_add_ref( px );
00073     }
00074 
00075 #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00076 
00077     template<class U>
00078 #if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
00079 
00080     intrusive_ptr( intrusive_ptr<U> const & rhs, typename detail::sp_enable_if_convertible<U,T>::type = detail::sp_empty() )
00081 
00082 #else
00083 
00084     intrusive_ptr( intrusive_ptr<U> const & rhs )
00085 
00086 #endif
00087     : px( rhs.get() )
00088     {
00089         if( px != 0 ) intrusive_ptr_add_ref( px );
00090     }
00091 
00092 #endif
00093 
00094     intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px )
00095     {
00096         if( px != 0 ) intrusive_ptr_add_ref( px );
00097     }
00098 
00099     ~intrusive_ptr()
00100     {
00101         if( px != 0 ) intrusive_ptr_release( px );
00102     }
00103 
00104 #if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00105 
00106     template<class U> intrusive_ptr & operator=(intrusive_ptr<U> const & rhs)
00107     {
00108         this_type(rhs).swap(*this);
00109         return *this;
00110     }
00111 
00112 #endif
00113 
00114     intrusive_ptr & operator=(intrusive_ptr const & rhs)
00115     {
00116         this_type(rhs).swap(*this);
00117         return *this;
00118     }
00119 
00120     intrusive_ptr & operator=(T * rhs)
00121     {
00122         this_type(rhs).swap(*this);
00123         return *this;
00124     }
00125 
00126     void reset()
00127     {
00128         this_type().swap( *this );
00129     }
00130 
00131     void reset( T * rhs )
00132     {
00133         this_type( rhs ).swap( *this );
00134     }
00135 
00136     T * get() const
00137     {
00138         return px;
00139     }
00140 
00141     T & operator*() const
00142     {
00143         BOOST_ASSERT( px != 0 );
00144         return *px;
00145     }
00146 
00147     T * operator->() const
00148     {
00149         BOOST_ASSERT( px != 0 );
00150         return px;
00151     }
00152 
00153 // implicit conversion to "bool"
00154 #include <boost/smart_ptr/detail/operator_bool.hpp>
00155 
00156     void swap(intrusive_ptr & rhs)
00157     {
00158         T * tmp = px;
00159         px = rhs.px;
00160         rhs.px = tmp;
00161     }
00162 
00163 private:
00164 
00165     T * px;
00166 };
00167 
00168 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
00169 {
00170     return a.get() == b.get();
00171 }
00172 
00173 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
00174 {
00175     return a.get() != b.get();
00176 }
00177 
00178 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
00179 {
00180     return a.get() == b;
00181 }
00182 
00183 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
00184 {
00185     return a.get() != b;
00186 }
00187 
00188 template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
00189 {
00190     return a == b.get();
00191 }
00192 
00193 template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
00194 {
00195     return a != b.get();
00196 }
00197 
00198 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00199 
00200 // Resolve the ambiguity between our op!= and the one in rel_ops
00201 
00202 template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
00203 {
00204     return a.get() != b.get();
00205 }
00206 
00207 #endif
00208 
00209 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
00210 {
00211     return std::less<T *>()(a.get(), b.get());
00212 }
00213 
00214 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
00215 {
00216     lhs.swap(rhs);
00217 }
00218 
00219 // mem_fn support
00220 
00221 template<class T> T * get_pointer(intrusive_ptr<T> const & p)
00222 {
00223     return p.get();
00224 }
00225 
00226 template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
00227 {
00228     return static_cast<T *>(p.get());
00229 }
00230 
00231 template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
00232 {
00233     return const_cast<T *>(p.get());
00234 }
00235 
00236 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
00237 {
00238     return dynamic_cast<T *>(p.get());
00239 }
00240 
00241 // operator<<
00242 
00243 #if !defined(BOOST_NO_IOSTREAM)
00244 
00245 #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
00246 
00247 template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
00248 {
00249     os << p.get();
00250     return os;
00251 }
00252 
00253 #else
00254 
00255 // in STLport's no-iostreams mode no iostream symbols can be used
00256 #ifndef _STLP_NO_IOSTREAMS
00257 
00258 # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
00259 // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
00260 using std::basic_ostream;
00261 template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
00262 # else
00263 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
00264 # endif 
00265 {
00266     os << p.get();
00267     return os;
00268 }
00269 
00270 #endif // _STLP_NO_IOSTREAMS
00271 
00272 #endif // __GNUC__ < 3
00273 
00274 #endif // !defined(BOOST_NO_IOSTREAM)
00275 
00276 } // namespace boost
00277 
00278 #ifdef BOOST_MSVC
00279 # pragma warning(pop)
00280 #endif    
00281 
00282 #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:29