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