00001 #ifndef __LDK_SMARTPOINTERS_HH__
00002 #define __LDK_SMARTPOINTERS_HH__
00003
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00028
00033
00034 #include "LDK/Memory.h"
00035 #include "LDK/Object.h"
00036
00037 namespace LDK
00038 {
00039
00043
00052
00053 template <class T>
00054 class SmartPointerBase
00055 {
00056 public:
00057 typedef T Type;
00058 typedef T* PointerType;
00059 typedef T& ReferenceType;
00060 protected:
00061 PointerType mPtr;
00062
00063 SmartPointerBase(PointerType p=NULL) : mPtr(p) {}
00064
00065 class Tester
00066 {
00067 private:
00068 void operator delete(void*);
00069 public:
00070 Tester() {}
00071 };
00072
00073 public:
00074 inline static PointerType pointer(const SmartPointerBase& rhs) { return rhs.mPtr; }
00075
00076 inline operator Tester*() const
00077 {
00078 if(!mPtr)
00079 return NULL;
00080 static Tester test;
00081 return &test;
00082 }
00083
00084 inline PointerType operator->()
00085 {
00086 assert(mPtr);
00087 return mPtr;
00088 }
00089
00090 inline ReferenceType operator*()
00091 {
00092 assert(mPtr);
00093 return *mPtr;
00094 }
00095
00096 inline PointerType operator->() const
00097 {
00098 assert(mPtr);
00099 return mPtr;
00100 }
00101
00102 inline ReferenceType operator*() const
00103 {
00104 assert(mPtr);
00105 return *mPtr;
00106 }
00107
00108 inline bool operator!() const
00109 {
00110 return mPtr == NULL;
00111 }
00112
00113 inline friend bool operator==(const SmartPointerBase& lhs, const SmartPointerBase& rhs)
00114 {
00115 return pointer(lhs) == pointer(rhs);
00116 }
00117
00118 template <typename U>
00119 inline friend bool operator==(const SmartPointerBase& lhs, const U* rhs)
00120 {
00121 return pointer(lhs) == rhs;
00122 }
00123
00124 template <typename U>
00125 inline friend bool operator==(const U* lhs, const SmartPointerBase& rhs)
00126 {
00127 return pointer(rhs) == lhs;
00128 }
00129
00130 inline friend bool operator!=(const SmartPointerBase& lhs, const SmartPointerBase& rhs)
00131 {
00132 return pointer(lhs) != pointer(rhs);
00133 }
00134
00135 template <typename U>
00136 inline friend bool operator!=(const SmartPointerBase& lhs, const U* rhs)
00137 {
00138 return pointer(lhs) != rhs;
00139 }
00140
00141 template <typename U>
00142 inline friend bool operator!=(const U* lhs, const SmartPointerBase& rhs)
00143 {
00144 return pointer(rhs) != lhs;
00145 }
00146 };
00147
00153 template <class T>
00154 class IntrusiveSmartPointer : public SmartPointerBase<T>
00155 {
00156 inline static void incRefCount(IntrusiveSmartPointer& rhs)
00157 {
00158 if(rhs.mPtr)
00159 Object::incRef(*rhs.mPtr);
00160 }
00161
00162 inline static void decRefCount(IntrusiveSmartPointer& rhs)
00163 {
00164 if(rhs.mPtr)
00165 if(Object::decRef(*rhs.mPtr)==0)
00166 rhs.mPtr = NULL;
00167 }
00168
00169 public:
00170
00171 typedef typename SmartPointerBase<T>::PointerType PointerType;
00172
00173 inline static size_t refCount(const IntrusiveSmartPointer& s)
00174 {
00175 return Object::refCount(*s.mPtr);
00176 }
00177
00178 inline IntrusiveSmartPointer(PointerType p=NULL) :
00179 SmartPointerBase<T>(p)
00180 {
00181 incRefCount(*this);
00182 }
00183
00184 inline IntrusiveSmartPointer(const IntrusiveSmartPointer& rhs)
00185 : SmartPointerBase<T>(rhs.mPtr)
00186 {
00187 incRefCount(*this);
00188 }
00189
00190 inline ~IntrusiveSmartPointer()
00191 {
00192 decRefCount(*this);
00193 }
00194
00195 inline IntrusiveSmartPointer& operator=(const IntrusiveSmartPointer& rhs)
00196 {
00197 decRefCount(*this);
00198 SmartPointerBase<T>::mPtr = rhs.mPtr;
00199 incRefCount(*this);
00200 return *this;
00201 }
00202 };
00203
00210 template <class T>
00211 class SmartPointer : public SmartPointerBase<T>
00212 {
00213 protected:
00214 mutable size_t* mRefCountPtr;
00215
00216 inline static void incRefCount(SmartPointer& rhs)
00217 {
00218 assert(rhs.mRefCountPtr);
00219 ++(*rhs.mRefCountPtr);
00220 }
00221
00222 inline static void decRefCount(SmartPointer& rhs)
00223 {
00224 assert(rhs.mRefCountPtr);
00225 if(--(*rhs.mRefCountPtr) == 0)
00226 {
00227 LDK::destroy(rhs.mRefCountPtr);
00228 rhs.mRefCountPtr = NULL;
00229 if(rhs.mPtr)
00230 {
00231 LDK::destroy(rhs.mPtr);
00232 rhs.mPtr = NULL;
00233 }
00234 }
00235 }
00236
00237 public:
00238
00239 typedef typename SmartPointerBase<T>::PointerType PointerType;
00240
00241 inline static size_t refCount(const SmartPointer& s) { return *s.mRefCountPtr; }
00242
00243 inline SmartPointer(PointerType p=NULL) :
00244 SmartPointerBase<T>(NULL)
00245 {
00246 mRefCountPtr = LDK_CREATE1(size_t,1);
00247 SmartPointerBase<T>::mPtr = p;
00248 }
00249
00250 inline SmartPointer(const SmartPointer& rhs)
00251 : SmartPointerBase<T>(rhs.mPtr)
00252 , mRefCountPtr(rhs.mRefCountPtr)
00253 {
00254 incRefCount(*this);
00255 }
00256
00257 inline ~SmartPointer()
00258 {
00259 decRefCount(*this);
00260 }
00261
00262 inline SmartPointer& operator=(const SmartPointer& rhs)
00263 {
00264 decRefCount(*this);
00265 mRefCountPtr = rhs.mRefCountPtr;
00266 SmartPointerBase<T>::mPtr = rhs.mPtr;
00267 incRefCount(*this);
00268 return *this;
00269 }
00270 };
00271
00277 template <class T>
00278 class NewSmartPointer : public SmartPointerBase<T>
00279 {
00280 protected:
00281 mutable size_t* mRefCountPtr;
00282
00283 inline static void incRefCount(NewSmartPointer& rhs)
00284 {
00285 assert(rhs.mRefCountPtr);
00286 ++(*rhs.mRefCountPtr);
00287 }
00288
00289 inline static void decRefCount(NewSmartPointer& rhs)
00290 {
00291 assert(rhs.mRefCountPtr);
00292 if(--(*rhs.mRefCountPtr) == 0)
00293 {
00294 LDK::destroy(rhs.mRefCountPtr);
00295 rhs.mRefCountPtr = NULL;
00296 if(rhs.mPtr)
00297 {
00298 delete rhs.mPtr;
00299 rhs.mPtr = NULL;
00300 }
00301 }
00302 }
00303
00304 public:
00305
00306 typedef typename SmartPointerBase<T>::PointerType PointerType;
00307
00308 inline static size_t refCount(const NewSmartPointer& s) { return *s.mRefCountPtr; }
00309
00310 inline NewSmartPointer(PointerType p=NULL)
00311 {
00312 mRefCountPtr = LDK_CREATE1(size_t,1);
00313 SmartPointerBase<T>::mPtr = p;
00314 }
00315
00316 inline NewSmartPointer(const NewSmartPointer& rhs)
00317 : SmartPointerBase<T>(rhs.mPtr)
00318 , mRefCountPtr(rhs.mRefCountPtr)
00319 {
00320 incRefCount(*this);
00321 }
00322
00323 inline ~NewSmartPointer()
00324 {
00325 decRefCount(*this);
00326 }
00327
00328 inline NewSmartPointer& operator=(const NewSmartPointer& rhs)
00329 {
00330 decRefCount(*this);
00331 mRefCountPtr = rhs.mRefCountPtr;
00332 SmartPointerBase<T>::mPtr = rhs.mPtr;
00333 incRefCount(*this);
00334 return *this;
00335 }
00336 };
00337
00343 template <class T>
00344 class RawSmartPointer : public SmartPointerBase<T>
00345 {
00346 protected:
00347 mutable size_t* mRefCountPtr;
00348
00349 inline static void incRefCount(RawSmartPointer& rhs)
00350 {
00351 assert(rhs.mRefCountPtr);
00352 ++(*rhs.mRefCountPtr);
00353 }
00354
00355 inline static void decRefCount(RawSmartPointer& rhs)
00356 {
00357 assert(rhs.mRefCountPtr);
00358 if(--(*rhs.mRefCountPtr) == 0)
00359 {
00360 LDK::destroy(rhs.mRefCountPtr);
00361 rhs.mRefCountPtr = NULL;
00362 LDK::dealloc(rhs.mPtr);
00363 rhs.mPtr = NULL;
00364 }
00365 }
00366
00367 public:
00368
00369 typedef typename SmartPointerBase<T>::PointerType PointerType;
00370
00371 inline static size_t refCount(const RawSmartPointer& s) { return *s.mRefCountPtr; }
00372
00373 inline RawSmartPointer(PointerType p=NULL)
00374 {
00375 mRefCountPtr = LDK_CREATE1(size_t,1);
00376 SmartPointerBase<T>::mPtr = p;
00377 }
00378
00379 inline RawSmartPointer(const RawSmartPointer& rhs)
00380 : SmartPointerBase<T>(rhs.mPtr)
00381 , mRefCountPtr(rhs.mRefCountPtr)
00382 {
00383 incRefCount(*this);
00384 }
00385
00386 inline ~RawSmartPointer()
00387 {
00388 decRefCount(*this);
00389 }
00390
00391 inline RawSmartPointer& operator=(const RawSmartPointer& rhs)
00392 {
00393 decRefCount(*this);
00394 mRefCountPtr = rhs.mRefCountPtr;
00395 SmartPointerBase<T>::mPtr = rhs.mPtr;
00396 incRefCount(*this);
00397 return *this;
00398 }
00399 };
00400
00402
00403 }
00404
00405
00406 #endif //__LDK_SMARTPOINTERS_HH__