00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef RPTR_RPTR_HDR
00023 #define RPTR_RPTR_HDR
00024
00025 #include "debug.h"
00026
00052 namespace rptr {
00053
00055 struct Rptr_ReferenceCounter {
00056 inline void Attach() {
00057 ++counter;
00058 }
00059 template<class T>
00060 inline void Detach(T *p) {
00061 if(--counter==0) {
00062 if(owner) {
00063 delete p;
00064 }
00065 delete this;
00066 }
00067 }
00068 inline Rptr_ReferenceCounter(bool owner0):
00069 owner(owner0), counter(0) {}
00070
00071 bool owner;
00072 private:
00073 unsigned counter;
00074 };
00075
00077
00101 template<class T>
00102 class Rptr {
00104 Rptr_ReferenceCounter *refcounter;
00106 T *data;
00107
00108 template<class TT>
00109 inline static void Dummy(TT * const &) {}
00110
00111 public:
00112 template<class TT> friend class Rptr;
00114
00115
00116 inline Rptr():
00117 refcounter(0),
00118 data(0)
00119 {
00120 }
00122 inline Rptr(const Rptr &src):
00123 refcounter(src.refcounter),
00124 data(src.data)
00125 {
00126 if(refcounter) {
00127 refcounter->Attach();
00128 }
00129 }
00136 inline Rptr(T *data0, bool owner0=true):
00137 refcounter(0),
00138 data(data0)
00139 {
00140 if(data) {
00141 refcounter = new Rptr_ReferenceCounter(owner0);
00142 refcounter->Attach();
00143 }
00144 }
00147 inline Rptr & Set(T *src, bool owner0=true)
00148 {
00149 if(refcounter) {
00150 refcounter->Detach(data);
00151 }
00152 refcounter = 0;
00153 data = src;
00154 if(data) {
00155 refcounter = new Rptr_ReferenceCounter(owner0);
00156 refcounter->Attach();
00157 }
00158 return *this;
00159 }
00161 inline ~Rptr()
00162 {
00163 if(refcounter) {
00164 refcounter->Detach(data);
00165 }
00166 }
00168
00169
00170
00171 inline T & operator *() const {
00172 RPTR_DEBUG_CHECK_NULL(data);
00173 return *data;
00174 }
00176 inline T * operator ->() const {
00177 RPTR_DEBUG_CHECK_NULL(data);
00178 return data;
00179 }
00181 template<class TT>
00182 inline operator const Rptr<TT> & () const {
00183 Dummy<TT>(data);
00184
00185 return reinterpret_cast<const Rptr<TT> &>(*this);
00186 }
00188 inline T * Ptr() const {
00189 return data;
00190 }
00193 inline bool IsOwner() const {
00194 return refcounter && refcounter->owner;
00195 }
00198 inline T * Drop() const {
00199 if(refcounter) {
00200 refcounter->owner = false;
00201 }
00202 return data;
00203 }
00205 inline bool operator ==(const Rptr &rhs) const {
00206 return data == rhs.data;
00207 }
00209 inline bool operator ==(const T *rhs) const {
00210 return data == rhs;
00211 }
00213 inline bool operator !=(const Rptr &rhs) const {
00214 return data != rhs.data;
00215 }
00217 inline bool operator !=(const T *rhs) const {
00218 return data != rhs;
00219 }
00221
00222
00223
00224 inline Rptr & operator =(const Rptr &src) {
00225 Rptr_ReferenceCounter *tmp = refcounter;
00226 T *tmpdata = data;
00227 data=src.data;
00228 refcounter=src.refcounter;
00229 if(refcounter) {
00230 refcounter->Attach();
00231 }
00232 if(tmp) {
00233 tmp->Detach(tmpdata);
00234 }
00235 return *this;
00236 }
00237
00239 inline Rptr & operator =(T *src) {
00240 return Set(src,true);
00241 }
00242
00244 template<class TT>
00245 inline Rptr & DynamicCast(const Rptr<TT> &src) {
00246 Rptr_ReferenceCounter *tmp=refcounter;
00247 T *tmpdata = data;
00248 refcounter = 0;
00249 data=dynamic_cast<T *>(src.data);
00250 if(data) {
00251 refcounter = src.refcounter;
00252 refcounter->Attach();
00253 }
00254 if(tmp) {
00255 tmp->Detach(tmpdata);
00256 }
00257 return *this;
00258 }
00260 template<class TT>
00261 inline Rptr & StaticCast(const Rptr<TT> &src) {
00262 Rptr_ReferenceCounter *tmp=refcounter;
00263 T *tmpdata = data;
00264 refcounter = 0;
00265 data=static_cast<T *>(src.data);
00266 if(data) {
00267 refcounter = src.refcounter;
00268 refcounter->Attach();
00269 }
00270 if(tmp) {
00271 tmp->Detach(tmpdata);
00272 }
00273 return *this;
00274 }
00276 };
00277
00278 }
00279 #endif