TCSharedPtrImpl.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _TC_SHARED_PTR_IMP_H_
00036 #define _TC_SHARED_PTR_IMP_H_
00037
00038 #include "TCInterlocked.h"
00039
00040 #include <memory>
00041 #include <algorithm>
00042
00043 #include "TCNewEnable.h"
00044
00045 namespace TC
00046 {
00047 class WeakPtrCount;
00048 class SharedPtrCount;
00049
00067 namespace Impl
00068 {
00070 class SharedPtrCountBase
00071 {
00072 protected:
00073 virtual ~SharedPtrCountBase() {}
00074 virtual void DeletePtr() = 0;
00075
00077 SharedPtrCountBase()
00078 :m_count(1),
00079 m_weak_count(1)
00080 {
00081 }
00082
00083 private:
00085 inline void AddReference()
00086 {
00087 Interlocked::Increment(m_count);
00088 }
00093 inline void ReleaseReference()
00094 {
00095 if (Interlocked::Decrement(m_count) == 0)
00096 {
00097 DeletePtr();
00098 ReleaseWeakReference();
00099 }
00100 }
00102 inline uint32 GetUseCount() const { return m_count;}
00103
00105 inline void AddWeakReference()
00106 {
00107 Interlocked::Increment(m_weak_count);
00108 }
00113 inline void ReleaseWeakReference()
00114 {
00115 if (Interlocked::Decrement(m_weak_count) == 0)
00116 {
00117 Destroy();
00118 }
00119 }
00120
00125 inline void Destroy() { delete this;}
00126
00127 private:
00129 Interlocked::Type m_count;
00131 Interlocked::Type m_weak_count;
00132
00133 friend class TC::SharedPtrCount;
00134 friend class TC::WeakPtrCount;
00135 };
00136
00141 template <class T, class DELETER>
00142 class SharedPtrCountType: protected SharedPtrCountBase
00143 {
00144 protected:
00146 SharedPtrCountType(T* ptr, DELETER deleter)
00147 :m_ptr(ptr),
00148 m_deleter(deleter)
00149 {
00150 }
00151
00152 virtual void DeletePtr()
00153 {
00154 m_deleter(m_ptr);
00155 }
00156 private:
00158 T* m_ptr;
00160 DELETER m_deleter;
00161
00162 friend class TC::SharedPtrCount;
00163 };
00164
00165 }
00166
00168 class SharedPtrCount
00169 {
00170 public:
00172 SharedPtrCount():m_count(0) {}
00173
00175 template <class PTR_TYPE, class DELETER>
00176 SharedPtrCount(PTR_TYPE* ptr, DELETER deleter)
00177 {
00178 m_count = new Impl::SharedPtrCountType<PTR_TYPE, DELETER>(ptr, deleter);
00179 }
00180
00182 template <class PTR_TYPE, class DELETER>
00183 SharedPtrCount(std::auto_ptr<PTR_TYPE>& ptr, DELETER deleter)
00184 {
00185 m_count = new Impl::SharedPtrCountType<PTR_TYPE, DELETER>(ptr.get(), deleter);
00186 ptr.release();
00187 }
00188
00190 explicit SharedPtrCount(const SharedPtrCount& count)
00191 :m_count(count.m_count)
00192 {
00193 if (m_count) m_count->AddReference();
00194 }
00195
00197 explicit SharedPtrCount(const WeakPtrCount& count);
00198
00200 ~SharedPtrCount()
00201 {
00202 if (m_count)
00203 {
00204 m_count->ReleaseReference();
00205 m_count = 0;
00206 }
00207 }
00208
00213 SharedPtrCount& operator=(const SharedPtrCount& count)
00214 {
00215 if (count.m_count != m_count)
00216 {
00217 if (count.m_count) count.m_count->AddReference();
00218 if (m_count) m_count->ReleaseReference();
00219 m_count = count.m_count;
00220 }
00221
00222 return *this;
00223 }
00224
00226 uint32 GetUseCount() const
00227 {
00228 return m_count ? m_count->GetUseCount() : 0;
00229 }
00230
00232 void Swap(SharedPtrCount& a)
00233 {
00234 std::swap(m_count, a.m_count);
00235 }
00236
00238 friend inline bool operator==(const SharedPtrCount& a, const SharedPtrCount& b)
00239 {
00240 return a.m_count == b.m_count;
00241 }
00242
00244 friend inline bool operator<(const SharedPtrCount& a, const SharedPtrCount& b)
00245 {
00246 return a.m_count < b.m_count;;
00247 }
00248
00249 private:
00251 Impl::SharedPtrCountBase* m_count;
00252 friend class TC::WeakPtrCount;
00253 };
00254
00256 class WeakPtrCount
00257 {
00258 public:
00259 WeakPtrCount() :m_count(0) {}
00260
00262 explicit WeakPtrCount(const WeakPtrCount& r) :m_count(r.m_count)
00263 {
00264 if (m_count != 0) m_count->AddWeakReference();
00265 }
00266
00268 explicit WeakPtrCount(const SharedPtrCount& r) :m_count(r.m_count)
00269 {
00270 if (m_count != 0) m_count->AddWeakReference();
00271 }
00272
00274 ~WeakPtrCount()
00275 {
00276 if (m_count != 0)
00277 {
00278 m_count->ReleaseWeakReference();
00279 m_count = 0;
00280 }
00281 }
00282
00284 WeakPtrCount& operator=(const SharedPtrCount& r)
00285 {
00286 if (r.m_count != 0) r.m_count->AddWeakReference();
00287 if (m_count != 0) m_count->ReleaseWeakReference();
00288 m_count = r.m_count;
00289
00290 return *this;
00291 }
00292
00294 WeakPtrCount& operator=(const WeakPtrCount& r)
00295 {
00296 if (r.m_count != 0) r.m_count->AddWeakReference();
00297 if (m_count != 0) m_count->ReleaseWeakReference();
00298 m_count = r.m_count;
00299
00300 return *this;
00301 }
00302
00304 uint32 GetUseCount() const
00305 {
00306 return m_count != 0 ? m_count->GetUseCount(): 0;
00307 }
00308
00310 void Swap(WeakPtrCount& a)
00311 {
00312 std::swap(m_count, a.m_count);
00313 }
00314
00316 friend inline bool operator==(const WeakPtrCount& a, const WeakPtrCount& b)
00317 {
00318 return a.m_count == b.m_count;
00319 }
00320
00322 friend inline bool operator<(const WeakPtrCount& a, const WeakPtrCount& b)
00323 {
00324 return a.m_count < b.m_count;
00325 }
00326
00327 private:
00329 Impl::SharedPtrCountBase* m_count;
00330 friend class TC::SharedPtrCount;
00331 };
00332
00333
00338 inline SharedPtrCount::SharedPtrCount(const WeakPtrCount& count)
00339 :m_count(count.m_count)
00340 {
00341 if (m_count) m_count->AddReference();
00342 }
00343
00344 }
00345
00346 #include "TCNewDisable.h"
00347
00348 #endif // _TC_SHARED_PTR_IMP_H_
00349