00001 /* $Id: countedptr.hpp 17248 2009-08-21 20:21:05Z rubidium $ */ 00002 00003 /* 00004 * This file is part of OpenTTD. 00005 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. 00006 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00007 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. 00008 */ 00009 00012 #ifndef COUNTEDPTR_HPP 00013 #define COUNTEDPTR_HPP 00014 00025 template <class Tcls_> 00026 class CCountedPtr { 00028 public: 00029 typedef Tcls_ Tcls; 00030 00031 protected: 00033 Tcls *m_pT; 00034 00035 public: 00037 FORCEINLINE CCountedPtr(Tcls *pObj = NULL) : m_pT(pObj) {AddRef();}; 00038 00040 FORCEINLINE CCountedPtr(const CCountedPtr& src) : m_pT(src.m_pT) {AddRef();}; 00041 00043 FORCEINLINE ~CCountedPtr() {Release();}; 00044 00045 protected: 00047 FORCEINLINE void AddRef() {if (m_pT != NULL) m_pT->AddRef();} 00048 00049 public: 00051 FORCEINLINE void Release() {if (m_pT != NULL) {Tcls *pT = m_pT; m_pT = NULL; pT->Release();}} 00052 00054 FORCEINLINE const Tcls *operator -> () const {assert(m_pT != NULL); return m_pT;}; 00055 00057 FORCEINLINE Tcls *operator -> () {assert(m_pT != NULL); return m_pT;}; 00058 00060 FORCEINLINE operator const Tcls*() const {assert(m_pT == NULL); return m_pT;} 00061 00063 FORCEINLINE operator Tcls*() {return m_pT;} 00064 00066 FORCEINLINE Tcls** operator &() {assert(m_pT == NULL); return &m_pT;} 00067 00069 FORCEINLINE CCountedPtr& operator = (Tcls *pT) {Assign(pT); return *this;} 00070 00072 FORCEINLINE CCountedPtr& operator = (const CCountedPtr& src) {Assign(src.m_pT); return *this;} 00073 00075 FORCEINLINE void Assign(Tcls *pT); 00076 00078 FORCEINLINE bool IsNull() const {return m_pT == NULL;} 00079 00081 //FORCEINLINE bool operator == (const CCountedPtr& sp) const {return m_pT == sp.m_pT;} 00082 00084 //FORCEINLINE bool operator != (const CCountedPtr& sp) const {return m_pT != sp.m_pT;} 00085 00087 FORCEINLINE void Attach(Tcls *pT) {Release(); m_pT = pT;} 00088 00090 FORCEINLINE Tcls *Detach() {Tcls *pT = m_pT; m_pT = NULL; return pT;} 00091 }; 00092 00093 template <class Tcls_> 00094 FORCEINLINE void CCountedPtr<Tcls_>::Assign(Tcls *pT) 00095 { 00096 /* if they are the same, we do nothing */ 00097 if (pT != m_pT) { 00098 if (pT) pT->AddRef(); // AddRef new pointer if any 00099 Tcls *pTold = m_pT; // save original ptr 00100 m_pT = pT; // update m_pT to new value 00101 if (pTold) pTold->Release(); // release old ptr if any 00102 } 00103 } 00104 00110 template <class T> struct AdaptT { 00111 T m_t; 00112 00114 AdaptT(const T &t) 00115 : m_t(t) 00116 {} 00117 00119 T& operator = (const T &t) 00120 { 00121 m_t = t; 00122 return t; 00123 } 00124 00126 operator T& () 00127 { 00128 return m_t; 00129 } 00130 00132 operator const T& () const 00133 { 00134 return m_t; 00135 } 00136 }; 00137 00138 00147 struct SimpleCountedObject { 00148 int32 m_ref_cnt; 00149 00150 SimpleCountedObject() 00151 : m_ref_cnt(0) 00152 {} 00153 00154 virtual ~SimpleCountedObject() 00155 {}; 00156 00157 virtual int32 AddRef(); 00158 virtual int32 Release(); 00159 virtual void FinalRelease() {}; 00160 }; 00161 00162 00163 00164 00165 #endif /* COUNTEDPTR_HPP */