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 #ifndef __ZRefCount__
00026 #define __ZRefCount__ 1
00027 #include "zconfig.h"
00028
00029 #include "ZDebug.h"
00030 #include "ZThread.h"
00031
00032 #include "ZCompat_operator_bool.h"
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef ZCONFIG_RefCount_CheckAccessDefault
00053 # define ZCONFIG_RefCount_CheckAccessDefault (ZCONFIG_Debug > 0)
00054 #endif
00055
00056
00057 #pragma mark -
00058 #pragma mark * ZRefCounted
00059
00060 class ZRefCounted
00061 {
00062 public:
00063 ZRefCounted() { ZThreadSafe_Set(fRefCount, 0); }
00064 virtual ~ZRefCounted();
00065
00066 int GetRefCount() const { return ZThreadSafe_Get(fRefCount); }
00067
00068 static void sIncRefCount(ZRefCounted* iObject)
00069 {
00070 if (iObject)
00071 ZThreadSafe_Inc(iObject->fRefCount);
00072 }
00073 static void sDecRefCount(ZRefCounted* iObject)
00074 {
00075 if (iObject && ZThreadSafe_DecAndTest(iObject->fRefCount))
00076 delete iObject;
00077 }
00078
00079 static void sCheckAccess(ZRefCounted* iObject);
00080
00081 static bool sCheckAccessEnabled() { return ZCONFIG_RefCount_CheckAccessDefault; }
00082
00083 private:
00084 ZThreadSafe_t fRefCount;
00085 };
00086
00087
00088 #pragma mark -
00089 #pragma mark * ZRefCountedWithFinalization
00090
00091 class ZRefCountedWithFinalization
00092 {
00093 public:
00094 ZRefCountedWithFinalization() { ZThreadSafe_Set(fRefCount, 0); }
00095 virtual ~ZRefCountedWithFinalization();
00096
00097 int GetRefCount() const { return ZThreadSafe_Get(fRefCount); }
00098
00099 virtual void Initialize();
00100
00101 virtual void Finalize();
00102
00103 void FinalizationComplete();
00104
00105 static void sIncRefCount(ZRefCountedWithFinalization* iObject)
00106 {
00107 if (iObject && 0 == ZThreadSafe_IncReturnOld(iObject->fRefCount))
00108 iObject->Initialize();
00109 }
00110
00111 static void sDecRefCount(ZRefCountedWithFinalization* iObject);
00112
00113 static void sCheckAccess(ZRefCountedWithFinalization* iObject);
00114
00115 static bool sCheckAccessEnabled() { return ZCONFIG_RefCount_CheckAccessDefault; }
00116
00117 private:
00118 ZThreadSafe_t fRefCount;
00119 };
00120
00121
00122 #pragma mark -
00123 #pragma mark * ZRef declaration
00124
00125 template <class S> class ZRefSafe;
00126
00127 template <class T>
00128 class ZRef
00129 {
00130 private:
00131 ZOOLIB_DEFINE_OPERATOR_BOOL_TYPES_T(ZRef<T>,
00132 operator_bool_generator_type, operator_bool_type);
00133
00134 public:
00135 ZRef();
00136 ~ZRef();
00137
00138 ZRef(T* iObject);
00139 ZRef& operator=(T* iObject);
00140 bool operator==(const T* iObject) const;
00141 bool operator!=(const T* iObject) const;
00142
00143 ZRef(const ZRef& iOther);
00144 ZRef& operator=(const ZRef& iOther);
00145 bool operator==(const ZRef& iOther) const;
00146 bool operator!=(const ZRef& iOther) const;
00147
00148 template <class O> ZRef(const ZRef<O>& iOther);
00149 template <class O> ZRef& operator=(const ZRef<O>& iOther);
00150 template <class O> bool operator==(const ZRef<O>& iOther) const;
00151 template <class O> bool operator!=(const ZRef<O>& iOther) const;
00152 template <class O> bool operator<(const ZRef<O>& iOther) const;
00153
00154 template <class S> ZRef(const ZRefSafe<S>& iOther);
00155 template <class S> ZRef& operator=(const ZRefSafe<S>& iOther);
00156
00157 T* operator->() const;
00158
00159 operator operator_bool_type() const
00160 { return operator_bool_generator_type::translate(fObject); }
00161
00162 void Clear();
00163
00164 T* GetObject() const { return fObject; }
00165
00166 void swap(ZRef& iOther) { std::swap(fObject, iOther.fObject); }
00167
00168 private:
00169 T* fObject;
00170 };
00171
00172
00173 #pragma mark -
00174 #pragma mark * ZRefSafe declaration
00175
00176 template <class S>
00177 class ZRefSafe
00178 {
00179 ZOOLIB_DEFINE_OPERATOR_BOOL_TYPES_T(ZRefSafe<S>,
00180 operator_bool_generator_type, operator_bool_type);
00181
00182 ZRefSafe(const ZRefSafe&);
00183 const ZRefSafe& operator=(const ZRefSafe&);
00184 public:
00185 ZRefSafe();
00186 ~ZRefSafe();
00187
00188 ZRefSafe(S* iObject);
00189 ZRefSafe& operator=(S* iObject);
00190
00191 template <class T> ZRefSafe(const ZRef<T>& iOther);
00192 template <class T> ZRefSafe& operator=(const ZRef<T>& iOther);
00193
00194 operator operator_bool_type() const
00195 { return operator_bool_generator_type::translate(fObject); }
00196
00197 S* GetObject() const { return fObject; }
00198
00199 void Acquire() const { fMutex.Acquire(); }
00200 void Release() const { fMutex.Release(); }
00201
00202 private:
00203 mutable ZMutexNR fMutex;
00204 S* fObject;
00205 };
00206
00207
00208 #pragma mark -
00209 #pragma mark * ZRef inline definitions
00210
00211 namespace std {
00212 template <class T>
00213 inline void swap(ZRef<T>& a, ZRef<T>& b)
00214 { a.swap(b); }
00215 }
00216
00217 template <class T>
00218 inline ZRef<T>::ZRef()
00219 : fObject(nil)
00220 {}
00221
00222 template <class T>
00223 inline ZRef<T>::~ZRef()
00224 {
00225 T::sDecRefCount(fObject);
00226 }
00227
00228 template <class T>
00229 inline ZRef<T>::ZRef(T* iObject)
00230 : fObject(iObject)
00231 {
00232 T::sIncRefCount(fObject);
00233 }
00234
00235 template <class T>
00236 inline ZRef<T>& ZRef<T>::operator=(T* iObject)
00237 {
00238 T::sIncRefCount(iObject);
00239 T::sDecRefCount(fObject);
00240 fObject = iObject;
00241 return *this;
00242 }
00243
00244 template <class T>
00245 inline bool ZRef<T>::operator==(const T* iObject) const
00246 { return fObject == iObject; }
00247
00248 template <class T>
00249 inline bool ZRef<T>::operator!=(const T* iObject) const
00250 { return fObject != iObject; }
00251
00252 template <class T>
00253 inline ZRef<T>::ZRef(const ZRef& iOther)
00254 : fObject(iOther.GetObject())
00255 {
00256 T::sIncRefCount(fObject);
00257 }
00258
00259 template <class T>
00260 inline ZRef<T>& ZRef<T>::operator=(const ZRef& iOther)
00261 {
00262 T::sIncRefCount(iOther.GetObject());
00263 T::sDecRefCount(fObject);
00264 fObject = iOther.GetObject();
00265 return *this;
00266 }
00267
00268 template <class T>
00269 inline bool ZRef<T>::operator==(const ZRef& iOther) const
00270 { return fObject == iOther.GetObject(); }
00271
00272 template <class T>
00273 inline bool ZRef<T>::operator!=(const ZRef& iOther) const
00274 { return fObject != iOther.GetObject(); }
00275
00276 template <class T> template <class O>
00277 inline ZRef<T>::ZRef(const ZRef<O>& iOther)
00278 : fObject(iOther.GetObject())
00279 {
00280 T::sIncRefCount(fObject);
00281 }
00282
00283 template <class T> template <class O>
00284 inline ZRef<T>& ZRef<T>::operator=(const ZRef<O>& iOther)
00285 {
00286 O::sIncRefCount(iOther.GetObject());
00287 T::sDecRefCount(fObject);
00288 fObject = iOther.GetObject();
00289 return *this;
00290 }
00291
00292 template <class T> template <class O>
00293 inline bool ZRef<T>::operator==(const ZRef<O>& iOther) const
00294 { return fObject == iOther.GetObject(); }
00295
00296 template <class T> template <class O>
00297 inline bool ZRef<T>::operator!=(const ZRef<O>& iOther) const
00298 { return fObject != iOther.GetObject(); }
00299
00300 template <class T> template <class O>
00301 inline bool ZRef<T>::operator<(const ZRef<O>& iOther) const
00302 { return fObject < iOther.GetObject(); }
00303
00304 template <class T> template <class S>
00305 ZRef<T>::ZRef(const ZRefSafe<S>& iOther)
00306 {
00307 iOther.Acquire();
00308 fObject = iOther.GetObject();
00309 T::sIncRefCount(fObject);
00310 iOther.Release();
00311 }
00312
00313 template <class T> template <class S>
00314 ZRef<T>& ZRef<T>::operator=(const ZRefSafe<S>& iOther)
00315 {
00316 iOther.Acquire();
00317 T* temp = iOther.GetObject();
00318 S::sIncRefCount(temp);
00319 iOther.Release();
00320
00321 T::sDecRefCount(fObject);
00322 fObject = temp;
00323 }
00324
00325 template <class T>
00326 inline T* ZRef<T>::operator->() const
00327 {
00328 if (T::sCheckAccessEnabled())
00329 T::sCheckAccess(fObject);
00330 return fObject;
00331 }
00332
00333 template <class T>
00334 inline void ZRef<T>::Clear()
00335 {
00336 T::sDecRefCount(fObject);
00337 fObject = nil;
00338 }
00339
00340
00341 #pragma mark -
00342 #pragma mark * ZRefSafe inline definitions
00343
00344 template <class S>
00345 inline ZRefSafe<S>::ZRefSafe()
00346 : fObject(nil)
00347 {}
00348
00349 template <class S>
00350 inline ZRefSafe<S>::~ZRefSafe()
00351 {
00352 S::sDecRefCount(fObject);
00353 }
00354
00355 template <class S>
00356 inline ZRefSafe<S>::ZRefSafe(S* iObject)
00357 : fObject(iObject)
00358 {
00359 S::sIncRefCount(iObject);
00360 }
00361
00362 template <class S>
00363 inline ZRefSafe<S>& ZRefSafe<S>::operator=(S* iObject)
00364 {
00365 S::sIncRefCount(iObject);
00366
00367 fMutex.Acquire();
00368 S* temp = fObject;
00369 fObject = iObject;
00370 fMutex.Release();
00371
00372 S::sDecRefCount(temp);
00373 return *this;
00374 }
00375
00376 template <class S> template <class T>
00377 inline ZRefSafe<S>::ZRefSafe(const ZRef<T>& iOther)
00378 : fObject(iOther.GetObject())
00379 {
00380 S::sIncRefCount(fObject);
00381 }
00382
00383 template<class S> template <class T>
00384 inline ZRefSafe<S>& ZRefSafe<S>::operator=(const ZRef<T>& iOther)
00385 {
00386 T::sIncRefCount(iOther.GetObject());
00387
00388 fMutex.Acquire();
00389 S* temp = fObject;
00390 fObject = iOther.GetObject();
00391 fMutex.Release();
00392
00393 S::sDecRefCount(temp);
00394 return *this;
00395 }
00396
00397
00398 #pragma mark -
00399 #pragma mark * ZRef casts
00400
00401 template <class O, class T> inline O* ZRefDynamicCast(const ZRef<T>& iVal)
00402 { return dynamic_cast<O*>(iVal.GetObject()); }
00403
00404 template <class O, class T> inline O* ZRefStaticCast(const ZRef<T>& iVal)
00405 { return static_cast<O*>(iVal.GetObject()); }
00406
00407
00408
00409 #endif // __ZRefCount__