Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
7.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef SMARTPTR_H
  8. #define SMARTPTR_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. class CRefCountAccessor
  13. {
  14. public:
  15. template< class T >
  16. static void AddRef( T *pObj )
  17. {
  18. pObj->AddRef();
  19. }
  20. template< class T >
  21. static void Release( T *pObj )
  22. {
  23. pObj->Release();
  24. }
  25. };
  26. // This can be used if your objects use AddReference/ReleaseReference function names.
  27. class CRefCountAccessorLongName
  28. {
  29. public:
  30. template< class T >
  31. static void AddRef( T *pObj )
  32. {
  33. pObj->AddReference();
  34. }
  35. template< class T >
  36. static void Release( T *pObj )
  37. {
  38. pObj->ReleaseReference();
  39. }
  40. };
  41. //
  42. // CPlainAutoPtr
  43. // is a smart wrapper for a pointer on the stack that performs "delete" upon destruction.
  44. //
  45. // No reference counting is performed, copying is prohibited "s_p2.Attach( s_p1.Detach() )" should be used
  46. // for readability and ease of maintenance.
  47. //
  48. // Auto pointer supports an "arrow" operator for invoking methods on the pointee and a "dereference" operator
  49. // for getting a pointee reference.
  50. //
  51. // No automatic casting to bool/ptrtype is performed to avoid bugs and problems (read on "safe bool idiom"
  52. // if casting to bool or pointer happens to be useful).
  53. //
  54. // Test for validity with "IsValid", get the pointer with "Get".
  55. //
  56. template < typename T >
  57. class CPlainAutoPtr
  58. {
  59. public:
  60. explicit CPlainAutoPtr( T *p = NULL ) : m_p( p ) {}
  61. ~CPlainAutoPtr( void ) { Delete(); }
  62. public:
  63. void Delete( void ) { delete Detach(); }
  64. private: // Disallow copying, use Detach() instead to avoid ambiguity
  65. CPlainAutoPtr( CPlainAutoPtr const &x );
  66. CPlainAutoPtr & operator = ( CPlainAutoPtr const &x );
  67. public:
  68. void Attach( T *p ) { m_p = p; }
  69. T * Detach( void ) { T * p( m_p ); m_p = NULL; return p; }
  70. public:
  71. bool IsValid( void ) const { return m_p != NULL; }
  72. T * Get( void ) const { return m_p; }
  73. T * operator -> ( void ) const { return Get(); }
  74. T & operator * ( void ) const { return *Get(); }
  75. private:
  76. T * m_p;
  77. };
  78. //
  79. // CArrayAutoPtr
  80. // is a smart wrapper for an array pointer on the stack that performs "delete []" upon destruction.
  81. //
  82. // No reference counting is performed, copying is prohibited "s_p2.Attach( s_p1.Detach() )" should be used
  83. // for readability and ease of maintenance.
  84. //
  85. // Auto pointer supports an "indexing" operator for accessing array elements.
  86. //
  87. // No automatic casting to bool/ptrtype is performed to avoid bugs and problems (read on "safe bool idiom"
  88. // if casting to bool or pointer happens to be useful).
  89. //
  90. // Test for validity with "IsValid", get the array pointer with "Get".
  91. //
  92. template < typename T >
  93. class CArrayAutoPtr : public CPlainAutoPtr < T > // Warning: no polymorphic destructor (delete on base class will be a mistake)
  94. {
  95. public:
  96. explicit CArrayAutoPtr( T *p = NULL ) { this->Attach( p ); }
  97. ~CArrayAutoPtr( void ) { this->Delete(); }
  98. public:
  99. void Delete( void ) { delete [] CPlainAutoPtr < T >::Detach(); }
  100. public:
  101. T & operator [] ( int k ) const { return CPlainAutoPtr < T >::Get()[ k ]; }
  102. };
  103. // Smart pointers can be used to automatically free an object when nobody points
  104. // at it anymore. Things contained in smart pointers must implement AddRef and Release
  105. // functions. If those functions are private, then the class must make
  106. // CRefCountAccessor a friend.
  107. template<class T, class RefCountAccessor=CRefCountAccessor>
  108. class CSmartPtr
  109. {
  110. public:
  111. CSmartPtr();
  112. CSmartPtr( T *pObj );
  113. CSmartPtr( const CSmartPtr<T,RefCountAccessor> &other );
  114. ~CSmartPtr();
  115. T* operator=( T *pObj );
  116. void operator=( const CSmartPtr<T,RefCountAccessor> &other );
  117. const T* operator->() const;
  118. T* operator->();
  119. bool operator!() const;
  120. bool operator==( const T *pOther ) const;
  121. bool IsValid() const; // Tells if the pointer is valid.
  122. T* GetObject() const; // Get temporary object pointer, don't store it for later reuse!
  123. void MarkDeleted();
  124. private:
  125. T *m_pObj;
  126. };
  127. template< class T, class RefCountAccessor >
  128. inline CSmartPtr<T,RefCountAccessor>::CSmartPtr()
  129. {
  130. m_pObj = NULL;
  131. }
  132. template< class T, class RefCountAccessor >
  133. inline CSmartPtr<T,RefCountAccessor>::CSmartPtr( T *pObj )
  134. {
  135. m_pObj = NULL;
  136. *this = pObj;
  137. }
  138. template< class T, class RefCountAccessor >
  139. inline CSmartPtr<T,RefCountAccessor>::CSmartPtr( const CSmartPtr<T,RefCountAccessor> &other )
  140. {
  141. m_pObj = NULL;
  142. *this = other;
  143. }
  144. template< class T, class RefCountAccessor >
  145. inline CSmartPtr<T,RefCountAccessor>::~CSmartPtr()
  146. {
  147. if ( m_pObj )
  148. {
  149. RefCountAccessor::Release( m_pObj );
  150. }
  151. }
  152. template< class T, class RefCountAccessor >
  153. inline T* CSmartPtr<T,RefCountAccessor>::operator=( T *pObj )
  154. {
  155. if ( pObj == m_pObj )
  156. return pObj;
  157. if ( pObj )
  158. {
  159. RefCountAccessor::AddRef( pObj );
  160. }
  161. if ( m_pObj )
  162. {
  163. RefCountAccessor::Release( m_pObj );
  164. }
  165. m_pObj = pObj;
  166. return pObj;
  167. }
  168. template< class T, class RefCountAccessor >
  169. inline void CSmartPtr<T,RefCountAccessor>::MarkDeleted()
  170. {
  171. m_pObj = NULL;
  172. }
  173. template< class T, class RefCountAccessor >
  174. inline void CSmartPtr<T,RefCountAccessor>::operator=( const CSmartPtr<T,RefCountAccessor> &other )
  175. {
  176. *this = other.m_pObj;
  177. }
  178. template< class T, class RefCountAccessor >
  179. inline const T* CSmartPtr<T,RefCountAccessor>::operator->() const
  180. {
  181. return m_pObj;
  182. }
  183. template< class T, class RefCountAccessor >
  184. inline T* CSmartPtr<T,RefCountAccessor>::operator->()
  185. {
  186. return m_pObj;
  187. }
  188. template< class T, class RefCountAccessor >
  189. inline bool CSmartPtr<T,RefCountAccessor>::operator!() const
  190. {
  191. return !m_pObj;
  192. }
  193. template< class T, class RefCountAccessor >
  194. inline bool CSmartPtr<T,RefCountAccessor>::operator==( const T *pOther ) const
  195. {
  196. return m_pObj == pOther;
  197. }
  198. template< class T, class RefCountAccessor >
  199. inline bool CSmartPtr<T,RefCountAccessor>::IsValid() const
  200. {
  201. return m_pObj != NULL;
  202. }
  203. template< class T, class RefCountAccessor >
  204. inline T* CSmartPtr<T,RefCountAccessor>::GetObject() const
  205. {
  206. return m_pObj;
  207. }
  208. //
  209. // CAutoPushPop
  210. // allows you to set value of a variable upon construction and destruction.
  211. // Constructors:
  212. // CAutoPushPop x( myvar )
  213. // saves the value and restores upon destruction.
  214. // CAutoPushPop x( myvar, newvalue )
  215. // saves the value, assigns new value upon construction, restores saved value upon destruction.
  216. // CAutoPushPop x( myvar, newvalue, restorevalue )
  217. // assigns new value upon construction, assignes restorevalue upon destruction.
  218. //
  219. template < typename T >
  220. class CAutoPushPop
  221. {
  222. public:
  223. explicit CAutoPushPop( T& var ) : m_rVar( var ), m_valPop( var ) {}
  224. CAutoPushPop( T& var, T const &valPush ) : m_rVar( var ), m_valPop( var ) { m_rVar = valPush; }
  225. CAutoPushPop( T& var, T const &valPush, T const &valPop ) : m_rVar( var ), m_valPop( var ) { m_rVar = valPush; }
  226. ~CAutoPushPop() { m_rVar = m_valPop; }
  227. private: // forbid copying
  228. CAutoPushPop( CAutoPushPop const &x );
  229. CAutoPushPop & operator = ( CAutoPushPop const &x );
  230. public:
  231. T & Get() { return m_rVar; }
  232. private:
  233. T &m_rVar;
  234. T m_valPop;
  235. };
  236. #endif // SMARTPTR_H