00001 /* $Id: countedptr.hpp 11914 2008-01-18 03:48:29Z glx $ */ 00002 00005 #ifndef COUNTEDPTR_HPP 00006 #define COUNTEDPTR_HPP 00007 00018 template <class Tcls_> 00019 class CCountedPtr { 00021 public: 00022 typedef Tcls_ Tcls; 00023 00024 protected: 00026 Tcls* m_pT; 00027 00028 public: 00030 FORCEINLINE CCountedPtr(Tcls* pObj = NULL) : m_pT(pObj) {AddRef();}; 00031 00033 FORCEINLINE CCountedPtr(const CCountedPtr& src) : m_pT(src.m_pT) {AddRef();}; 00034 00036 FORCEINLINE ~CCountedPtr() {Release();}; 00037 00038 protected: 00040 FORCEINLINE void AddRef() {if (m_pT != NULL) m_pT->AddRef();} 00041 00042 public: 00044 FORCEINLINE void Release() {if (m_pT != NULL) {Tcls* pT = m_pT; m_pT = NULL; pT->Release();}} 00045 00047 FORCEINLINE const Tcls* operator -> () const {assert(m_pT != NULL); return m_pT;}; 00048 00050 FORCEINLINE Tcls* operator -> () {assert(m_pT != NULL); return m_pT;}; 00051 00053 FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;} 00054 00056 FORCEINLINE operator Tcls*() {return m_pT;} 00057 00059 FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;} 00060 00062 FORCEINLINE CCountedPtr& operator = (Tcls* pT) {Assign(pT); return *this;} 00063 00065 FORCEINLINE CCountedPtr& operator = (const CCountedPtr& src) {Assign(src.m_pT); return *this;} 00066 00068 FORCEINLINE void Assign(Tcls* pT); 00069 00071 FORCEINLINE bool IsNull() const {return m_pT == NULL;} 00072 00074 //FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;} 00075 00077 //FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;} 00078 00080 FORCEINLINE void Attach(Tcls* pT) {Release(); m_pT = pT;} 00081 00083 FORCEINLINE Tcls* Detach() {Tcls* pT = m_pT; m_pT = NULL; return pT;} 00084 }; 00085 00086 template <class Tcls_> 00087 FORCEINLINE void CCountedPtr<Tcls_>::Assign(Tcls* pT) 00088 { 00089 // if they are the same, we do nothing 00090 if (pT != m_pT) { 00091 if (pT) pT->AddRef(); // AddRef new pointer if any 00092 Tcls* pTold = m_pT; // save original ptr 00093 m_pT = pT; // update m_pT to new value 00094 if (pTold) pTold->Release(); // release old ptr if any 00095 } 00096 } 00097 00103 template <class T> struct AdaptT { 00104 T m_t; 00105 00107 AdaptT(const T &t) 00108 : m_t(t) 00109 {} 00110 00112 T& operator = (const T &t) 00113 { 00114 m_t = t; 00115 return t; 00116 } 00117 00119 operator T& () 00120 { 00121 return m_t; 00122 } 00123 00125 operator const T& () const 00126 { 00127 return m_t; 00128 } 00129 }; 00130 00131 00140 struct SimpleCountedObject { 00141 int32 m_ref_cnt; 00142 00143 SimpleCountedObject() 00144 : m_ref_cnt(0) 00145 {} 00146 00147 virtual ~SimpleCountedObject() 00148 {}; 00149 00150 virtual int32 AddRef(); 00151 virtual int32 Release(); 00152 virtual void FinalRelease() {}; 00153 }; 00154 00155 00156 00157 00158 #endif /* COUNTEDPTR_HPP */