00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00066
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
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
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
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
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
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 }
00280
00281 #endif // OW32_RefCounted_h