CppCMS
|
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