Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

RefCounted.h

Go to the documentation of this file.
00001 /*  RefCounted.h - reference counted objects
00002     Copyright (C) 2001-2004 Mark Weaver
00003     Written by Mark Weaver <mark@npsl.co.uk>
00004 
00005     Part of the Open-Win32 library.
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public
00017     License along with this library; if not, write to the
00018     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA  02111-1307, USA.
00020 */
00021 
00026 #ifndef OW32_RefCounted_h
00027 #define OW32_RefCounted_h
00028 
00029 #include <OW32/OW32Libs.h>
00030 #include <OW32/windows.h>
00031 #include <cassert>
00032 
00033 namespace OW32
00034 {
00035 
00038 class OW32_LIB_EXPORT CRefCountedBase
00039 {
00040 protected:
00042     mutable LONG m_refCount;
00043 
00044 public:
00046     CRefCountedBase() :
00047         m_refCount(1)
00048     {
00049     }
00050 
00052     virtual ~CRefCountedBase() {}
00053 
00057     virtual LONG AddRef() const = 0;
00058 
00062     virtual LONG Release() const = 0;
00063 
00064 private:
00065     // No autogenerated copy or assignment c'tor 
00066     // (this would invalidate the reference counting)
00067     CRefCountedBase(const CRefCountedBase &other);
00068     CRefCountedBase& operator= (const CRefCountedBase &other);
00069 };
00070 
00073 class OW32_LIB_EXPORT CRefCounted : public CRefCountedBase
00074 {
00075 public:
00077     CRefCounted() {}
00078 
00082     virtual LONG AddRef() const
00083     {
00084         return InterlockedIncrement(&m_refCount);
00085     }
00086 
00087 
00091     virtual LONG Release() const
00092     {
00093         LONG newCount = InterlockedDecrement(&m_refCount);
00094         assert(newCount >= 0);
00095         if (newCount == 0)
00096             delete this;
00097         return newCount;
00098     }
00099 
00100 private:
00101     // No copy or assignment
00102     CRefCounted(const CRefCounted& other);
00103     CRefCounted &operator=(const CRefCounted& other);
00104 };
00105 
00110 class OW32_LIB_EXPORT CRefCountedSingleThread : public CRefCountedBase
00111 {
00112 public:
00114     CRefCountedSingleThread() {}
00115 
00119     virtual LONG AddRef() const
00120     {
00121         return ++m_refCount;
00122     }
00123 
00124 
00128     virtual LONG Release() const
00129     {
00130         LONG newCount = --m_refCount;
00131         if (newCount == 0)
00132             delete this;
00133         return newCount;
00134     }
00135 
00136 private:
00137     // No copy or assignment
00138     CRefCountedSingleThread(const CRefCountedSingleThread& other);
00139     CRefCountedSingleThread &operator=(const CRefCountedSingleThread& other);
00140 };
00141 
00142 
00146 template <class T>
00147 class CRefCountedWrapper : public CRefCounted, public T
00148 {
00149 public:
00151     CRefCountedWrapper() {}
00152 
00153 private:
00154     // No copy or assignment
00155     CRefCountedWrapper(const CRefCountedWrapper& other);
00156     CRefCountedWrapper &operator=(const CRefCountedWrapper& other);
00157 };
00158 
00164 template <class T>
00165 class CRefCountedWrapperSingleThread : public CRefCountedSingleThread, public T
00166 {
00167 public:
00169     CRefCountedWrapperSingleThread() {}
00170 
00171 private:
00172     // No copy or assignment
00173     CRefCountedWrapperSingleThread(const CRefCountedWrapperSingleThread& other);
00174     CRefCountedWrapperSingleThread &operator=(const CRefCountedWrapperSingleThread& other);
00175 };
00176 
00180 template <class T>
00181 class CAutoRefCountedPtr
00182 {
00183 private:
00184     T* m_pObj;
00185 
00186 public:
00188     CAutoRefCountedPtr() :
00189         m_pObj(0)
00190     {
00191     }
00192 
00198     CAutoRefCountedPtr(T* pObj, bool fAddRef=true) :
00199         m_pObj(pObj)
00200     {
00201         if (fAddRef && m_pObj) m_pObj->AddRef();
00202     }
00203 
00209     CAutoRefCountedPtr(const CAutoRefCountedPtr& other) {
00210         if (&other == this) { m_pObj = 0; return; }
00211         m_pObj = other.m_pObj;
00212         if (m_pObj) m_pObj->AddRef();
00213     }
00214 
00216     ~CAutoRefCountedPtr() {
00217         if (m_pObj) m_pObj->Release();
00218     }
00219 
00226     CAutoRefCountedPtr& operator=(const CAutoRefCountedPtr& other) {
00227         if (&other == this) return *this;
00228         if (m_pObj) m_pObj->Release();
00229         m_pObj = other.m_pObj;
00230         if (m_pObj) m_pObj->AddRef();
00231         return *this;
00232     }
00233 
00241     T* release() {
00242         T* pObj = m_pObj;
00243         m_pObj = 0;
00244         return pObj;
00245     }
00246 
00251     void reset(T* pObj, bool fAddRef = true) {
00252         if (m_pObj) m_pObj->Release();
00253         m_pObj = pObj;
00254         if (fAddRef && m_pObj) m_pObj->AddRef();
00255     }
00256 
00260     T* get() const {
00261         return m_pObj;
00262     }
00263 
00265     T* operator->() const { return m_pObj; }
00267     T& operator*() const { return *m_pObj; }
00269     operator T*() const { return m_pObj; }
00270 
00272     bool operator!() const { return m_pObj == 0; }
00273 
00274     /* \brief comparators as compiler can't deduce comparing a T* */
00275     bool operator<(const CAutoRefCountedPtr<T>& rhs) const { return m_pObj < rhs.m_pObj; }
00276     bool operator>(const CAutoRefCountedPtr<T>& rhs) const { return m_pObj > rhs.m_pObj; }
00277 };
00278 
00279 } // namespace OW32
00280 
00281 #endif // OW32_RefCounted_h

Generated on Sun Jun 5 01:29:18 2005 for OW32 by  doxygen 1.3.9.1