CppCMS
booster/intrusive_ptr.h
00001 #ifndef BOOSTER_INTRUSIVE_PTR_H_INCLUDED
00002 #define BOOSTER_INTRUSIVE_PTR_H_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 
00017 #include <functional>           // for std::less
00018 #include <iosfwd>               // for std::basic_ostream
00019 
00020 
00021 namespace booster
00022 {
00023 
00041 
00042 template<class T> class intrusive_ptr
00043 {
00044 private:
00045 
00046     typedef intrusive_ptr this_type;
00047 
00048 public:
00049 
00050     typedef T element_type;
00051 
00052     intrusive_ptr(): p_(0)
00053     {
00054     }
00055 
00056     intrusive_ptr(T * p, bool add_ref = true): p_(p)
00057     {
00058         if(p_ != 0 && add_ref) intrusive_ptr_add_ref(p_);
00059     }
00060 
00061     intrusive_ptr(intrusive_ptr const & rhs): p_(rhs.p_)
00062     {
00063         if(p_ != 0) intrusive_ptr_add_ref(p_);
00064     }
00065 
00066     ~intrusive_ptr()
00067     {
00068         if(p_ != 0) intrusive_ptr_release(p_);
00069     }
00070 
00071     template<class U> intrusive_ptr(intrusive_ptr<U> const & rhs): p_(rhs.get())
00072     {
00073         if(p_ != 0) intrusive_ptr_add_ref(p_);
00074     }
00075 
00076     intrusive_ptr & operator=(intrusive_ptr const & rhs)
00077     {
00078         this_type(rhs).swap(*this);
00079         return *this;
00080     }
00081 
00082     intrusive_ptr & operator=(T * rhs)
00083     {
00084         this_type(rhs).swap(*this);
00085         return *this;
00086     }
00087 
00088     T * get() const
00089     {
00090         return p_;
00091     }
00092 
00093     T & operator*() const
00094     {
00095         return *p_;
00096     }
00097 
00098     T * operator->() const
00099     {
00100         return p_;
00101     }
00102 
00103 
00104     typedef T * this_type::*unspecified_bool_type;
00105 
00106     operator unspecified_bool_type () const
00107     {
00108         return p_ == 0? 0: &this_type::p_;
00109     }
00110 
00111     // operator! is a Borland-specific workaround
00112     bool operator! () const
00113     {
00114         return p_ == 0;
00115     }
00116 
00117     void swap(intrusive_ptr & rhs)
00118     {
00119         T * tmp = p_;
00120         p_ = rhs.p_;
00121         rhs.p_ = tmp;
00122     }
00123 
00124 private:
00125 
00126     T * p_;
00127 };
00128 
00129 template<class T, class U> inline bool operator==(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
00130 {
00131     return a.get() == b.get();
00132 }
00133 
00134 template<class T, class U> inline bool operator!=(intrusive_ptr<T> const & a, intrusive_ptr<U> const & b)
00135 {
00136     return a.get() != b.get();
00137 }
00138 
00139 template<class T> inline bool operator==(intrusive_ptr<T> const & a, T * b)
00140 {
00141     return a.get() == b;
00142 }
00143 
00144 template<class T> inline bool operator!=(intrusive_ptr<T> const & a, T * b)
00145 {
00146     return a.get() != b;
00147 }
00148 
00149 template<class T> inline bool operator==(T * a, intrusive_ptr<T> const & b)
00150 {
00151     return a == b.get();
00152 }
00153 
00154 template<class T> inline bool operator!=(T * a, intrusive_ptr<T> const & b)
00155 {
00156     return a != b.get();
00157 }
00158 
00159 template<class T> inline bool operator<(intrusive_ptr<T> const & a, intrusive_ptr<T> const & b)
00160 {
00161     return std::less<T *>()(a.get(), b.get());
00162 }
00163 
00164 template<class T> void swap(intrusive_ptr<T> & lhs, intrusive_ptr<T> & rhs)
00165 {
00166     lhs.swap(rhs);
00167 }
00168 
00169 // mem_fn support
00170 
00171 template<class T> T * get_pointer(intrusive_ptr<T> const & p)
00172 {
00173     return p.get();
00174 }
00175 
00176 template<class T, class U> intrusive_ptr<T> static_pointer_cast(intrusive_ptr<U> const & p)
00177 {
00178     return static_cast<T *>(p.get());
00179 }
00180 
00181 template<class T, class U> intrusive_ptr<T> const_pointer_cast(intrusive_ptr<U> const & p)
00182 {
00183     return const_cast<T *>(p.get());
00184 }
00185 
00186 template<class T, class U> intrusive_ptr<T> dynamic_pointer_cast(intrusive_ptr<U> const & p)
00187 {
00188     return dynamic_cast<T *>(p.get());
00189 }
00190 
00191 // operator<<
00192 
00193 
00194 template<class E, class T, class Y> 
00195 std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, intrusive_ptr<Y> const & p)
00196 {
00197     os << p.get();
00198     return os;
00199 }
00200 
00201 
00202 } // namespace booster
00203 
00204 #endif  // #ifndef BOOSTER_INTRUSIVE_PTR_H_INCLUDED