imgtools/imglib/boostlibrary/boost/smart_ptr/intrusive_ptr.hpp
changeset 0 044383f39525
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     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 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     : 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     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 px;
       
   139     }
       
   140 
       
   141     T & operator*() const
       
   142     {
       
   143         BOOST_ASSERT( px != 0 );
       
   144         return *px;
       
   145     }
       
   146 
       
   147     T * operator->() const
       
   148     {
       
   149         BOOST_ASSERT( px != 0 );
       
   150         return px;
       
   151     }
       
   152 
       
   153 // implicit conversion to "bool"
       
   154 #include <boost/smart_ptr/detail/operator_bool.hpp>
       
   155 
       
   156     void swap(intrusive_ptr & rhs)
       
   157     {
       
   158         T * tmp = px;
       
   159         px = rhs.px;
       
   160         rhs.px = tmp;
       
   161     }
       
   162 
       
   163 private:
       
   164 
       
   165     T * px;
       
   166 };
       
   167 
       
   168 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
       
   169 {
       
   170     return a.get() == b.get();
       
   171 }
       
   172 
       
   173 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
       
   174 {
       
   175     return a.get() != b.get();
       
   176 }
       
   177 
       
   178 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, U * b)
       
   179 {
       
   180     return a.get() == b;
       
   181 }
       
   182 
       
   183 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, U * b)
       
   184 {
       
   185     return a.get() != b;
       
   186 }
       
   187 
       
   188 template<class T, class U> inline bool operator==(T * a, intrusive_ptr<U> const & b)
       
   189 {
       
   190     return a == b.get();
       
   191 }
       
   192 
       
   193 template<class T, class U> inline bool operator!=(T * a, intrusive_ptr<U> const & b)
       
   194 {
       
   195     return a != b.get();
       
   196 }
       
   197 
       
   198 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
       
   199 
       
   200 // Resolve the ambiguity between our op!= and the one in rel_ops
       
   201 
       
   202 template<class T> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
       
   203 {
       
   204     return a.get() != b.get();
       
   205 }
       
   206 
       
   207 #endif
       
   208 
       
   209 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
       
   210 {
       
   211     return std::less<T *>()(a.get(), b.get());
       
   212 }
       
   213 
       
   214 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
       
   215 {
       
   216     lhs.swap(rhs);
       
   217 }
       
   218 
       
   219 // mem_fn support
       
   220 
       
   221 template<class T> T * get_pointer(intrusive_ptr<T> const & p)
       
   222 {
       
   223     return p.get();
       
   224 }
       
   225 
       
   226 template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
       
   227 {
       
   228     return static_cast<T *>(p.get());
       
   229 }
       
   230 
       
   231 template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
       
   232 {
       
   233     return const_cast<T *>(p.get());
       
   234 }
       
   235 
       
   236 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
       
   237 {
       
   238     return dynamic_cast<T *>(p.get());
       
   239 }
       
   240 
       
   241 // operator<<
       
   242 
       
   243 #if !defined(BOOST_NO_IOSTREAM)
       
   244 
       
   245 #if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
       
   246 
       
   247 template<class Y> std::ostream & operator<< (std::ostream & os, intrusive_ptr<Y> const & p)
       
   248 {
       
   249     os << p.get();
       
   250     return os;
       
   251 }
       
   252 
       
   253 #else
       
   254 
       
   255 // in STLport's no-iostreams mode no iostream symbols can be used
       
   256 #ifndef _STLP_NO_IOSTREAMS
       
   257 
       
   258 # if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
       
   259 // MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
       
   260 using std::basic_ostream;
       
   261 template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
       
   262 # else
       
   263 template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
       
   264 # endif 
       
   265 {
       
   266     os << p.get();
       
   267     return os;
       
   268 }
       
   269 
       
   270 #endif // _STLP_NO_IOSTREAMS
       
   271 
       
   272 #endif // __GNUC__ < 3
       
   273 
       
   274 #endif // !defined(BOOST_NO_IOSTREAM)
       
   275 
       
   276 } // namespace boost
       
   277 
       
   278 #ifdef BOOST_MSVC
       
   279 # pragma warning(pop)
       
   280 #endif    
       
   281 
       
   282 #endif  // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED