SmartPointers.h

Go to the documentation of this file.
00001 #ifndef __LDK_SMARTPOINTERS_HH__
00002 #define __LDK_SMARTPOINTERS_HH__
00003 
00005 //   Copyright (C) 2003-2006 Lorien Dunn.
00006 //
00007 //   Contact: loriendunn AT users DOT sourceforge DOT net
00008 //
00009 //   This software is provided 'as-is', without any express or implied warranty.
00010 //   In no event will the authors be held liable for any damages arising from
00011 //   the use of this software.
00012 //
00013 //   Permission is granted to anyone to use this software for any purpose,
00014 //   including commercial applications, and to alter it and redistribute it
00015 //   freely, subject to the following restrictions:
00016 //
00017 //   1. The origin of this software must not be misrepresented; you must not
00018 //   claim that you wrote the original software. If you use this software in a
00019 //   product, an acknowledgment in the product documentation would be
00020 //   appreciated but is not required.
00021 //
00022 //   2. Altered source versions must be plainly marked as such, and must not be
00023 //   misrepresented as being the original software.
00024 //
00025 //   3. This notice may not be removed or altered from any source distribution.
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 // Enables "if (!sp) ..."
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 }// namespace LDK
00404 
00405 
00406 #endif //__LDK_SMARTPOINTERS_HH__

Generated on Fri Aug 17 18:32:26 2007 for LDK by  doxygen 1.5.1