epoc32/include/stdapis/boost/intrusive_ptr.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     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