00001 #ifndef BOOSTER_INTRUSIVE_PTR_H_INCLUDED
00002 #define BOOSTER_INTRUSIVE_PTR_H_INCLUDED
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <functional>
00018 #include <iosfwd>
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
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
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
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 }
00203
00204 #endif // #ifndef BOOSTER_INTRUSIVE_PTR_H_INCLUDED