Counter Strike : Global Offensive Source Code
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.

331 lines
7.9 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. // A stack based on a growable array
  8. //=============================================================================//
  9. #ifndef UTLSTACK_H
  10. #define UTLSTACK_H
  11. #include <assert.h>
  12. #include <string.h>
  13. #include "utlmemory.h"
  14. //-----------------------------------------------------------------------------
  15. // The CUtlStack class:
  16. // A growable stack class which doubles in size by default.
  17. // It will always keep all elements consecutive in memory, and may move the
  18. // elements around in memory (via a realloc) when elements are pushed or
  19. // popped. Clients should therefore refer to the elements of the stack
  20. // by index (they should *never* maintain pointers to elements in the stack).
  21. //-----------------------------------------------------------------------------
  22. template< class T, class M = CUtlMemory< T > >
  23. class CUtlStack
  24. {
  25. public:
  26. // constructor, destructor
  27. CUtlStack( int growSize = 0, int initSize = 0 );
  28. ~CUtlStack();
  29. void CopyFrom( const CUtlStack<T, M> &from );
  30. // element access
  31. T& operator[]( int i );
  32. T const& operator[]( int i ) const;
  33. T& Element( int i );
  34. T const& Element( int i ) const;
  35. // Gets the base address (can change when adding elements!)
  36. T* Base();
  37. T const* Base() const;
  38. // Looks at the stack top
  39. T& Top();
  40. T const& Top() const;
  41. // Size
  42. int Count() const;
  43. // Is element index valid?
  44. bool IsIdxValid( int i ) const;
  45. // Adds an element, uses default constructor
  46. int Push();
  47. // Adds an element, uses copy constructor
  48. int Push( T const& src );
  49. // Pops the stack
  50. void Pop();
  51. void Pop( T& oldTop );
  52. void PopMultiple( int num );
  53. // Makes sure we have enough memory allocated to store a requested # of elements
  54. void EnsureCapacity( int num );
  55. // Clears the stack, no deallocation
  56. void Clear();
  57. // Memory deallocation
  58. void Purge();
  59. private:
  60. // Grows the stack allocation
  61. void GrowStack();
  62. // For easier access to the elements through the debugger
  63. void ResetDbgInfo();
  64. M m_Memory;
  65. int m_Size;
  66. // For easier access to the elements through the debugger
  67. T* m_pElements;
  68. };
  69. //-----------------------------------------------------------------------------
  70. // For easier access to the elements through the debugger
  71. //-----------------------------------------------------------------------------
  72. template< class T, class M >
  73. inline void CUtlStack<T,M>::ResetDbgInfo()
  74. {
  75. m_pElements = m_Memory.Base();
  76. }
  77. //-----------------------------------------------------------------------------
  78. // constructor, destructor
  79. //-----------------------------------------------------------------------------
  80. template< class T, class M >
  81. CUtlStack<T,M>::CUtlStack( int growSize, int initSize ) :
  82. m_Memory(growSize, initSize), m_Size(0)
  83. {
  84. ResetDbgInfo();
  85. }
  86. template< class T, class M >
  87. CUtlStack<T,M>::~CUtlStack()
  88. {
  89. Purge();
  90. }
  91. //-----------------------------------------------------------------------------
  92. // copy into
  93. //-----------------------------------------------------------------------------
  94. template< class T, class M >
  95. void CUtlStack<T,M>::CopyFrom( const CUtlStack<T, M> &from )
  96. {
  97. Purge();
  98. EnsureCapacity( from.Count() );
  99. for ( int i = 0; i < from.Count(); i++ )
  100. {
  101. Push( from[i] );
  102. }
  103. }
  104. //-----------------------------------------------------------------------------
  105. // element access
  106. //-----------------------------------------------------------------------------
  107. template< class T, class M >
  108. inline T& CUtlStack<T,M>::operator[]( int i )
  109. {
  110. assert( IsIdxValid(i) );
  111. return m_Memory[i];
  112. }
  113. template< class T, class M >
  114. inline T const& CUtlStack<T,M>::operator[]( int i ) const
  115. {
  116. assert( IsIdxValid(i) );
  117. return m_Memory[i];
  118. }
  119. template< class T, class M >
  120. inline T& CUtlStack<T,M>::Element( int i )
  121. {
  122. assert( IsIdxValid(i) );
  123. return m_Memory[i];
  124. }
  125. template< class T, class M >
  126. inline T const& CUtlStack<T,M>::Element( int i ) const
  127. {
  128. assert( IsIdxValid(i) );
  129. return m_Memory[i];
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Gets the base address (can change when adding elements!)
  133. //-----------------------------------------------------------------------------
  134. template< class T, class M >
  135. inline T* CUtlStack<T,M>::Base()
  136. {
  137. return m_Memory.Base();
  138. }
  139. template< class T, class M >
  140. inline T const* CUtlStack<T,M>::Base() const
  141. {
  142. return m_Memory.Base();
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Returns the top of the stack
  146. //-----------------------------------------------------------------------------
  147. template< class T, class M >
  148. inline T& CUtlStack<T,M>::Top()
  149. {
  150. assert( m_Size > 0 );
  151. return Element(m_Size-1);
  152. }
  153. template< class T, class M >
  154. inline T const& CUtlStack<T,M>::Top() const
  155. {
  156. assert( m_Size > 0 );
  157. return Element(m_Size-1);
  158. }
  159. //-----------------------------------------------------------------------------
  160. // Size
  161. //-----------------------------------------------------------------------------
  162. template< class T, class M >
  163. inline int CUtlStack<T,M>::Count() const
  164. {
  165. return m_Size;
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Is element index valid?
  169. //-----------------------------------------------------------------------------
  170. template< class T, class M >
  171. inline bool CUtlStack<T,M>::IsIdxValid( int i ) const
  172. {
  173. return (i >= 0) && (i < m_Size);
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Grows the stack
  177. //-----------------------------------------------------------------------------
  178. template< class T, class M >
  179. void CUtlStack<T,M>::GrowStack()
  180. {
  181. if (m_Size >= m_Memory.NumAllocated())
  182. m_Memory.Grow();
  183. ++m_Size;
  184. ResetDbgInfo();
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Makes sure we have enough memory allocated to store a requested # of elements
  188. //-----------------------------------------------------------------------------
  189. template< class T, class M >
  190. void CUtlStack<T,M>::EnsureCapacity( int num )
  191. {
  192. m_Memory.EnsureCapacity(num);
  193. ResetDbgInfo();
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Adds an element, uses default constructor
  197. //-----------------------------------------------------------------------------
  198. template< class T, class M >
  199. int CUtlStack<T,M>::Push()
  200. {
  201. GrowStack();
  202. Construct( &Element(m_Size-1) );
  203. return m_Size - 1;
  204. }
  205. //-----------------------------------------------------------------------------
  206. // Adds an element, uses copy constructor
  207. //-----------------------------------------------------------------------------
  208. template< class T, class M >
  209. int CUtlStack<T,M>::Push( T const& src )
  210. {
  211. GrowStack();
  212. CopyConstruct( &Element(m_Size-1), src );
  213. return m_Size - 1;
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Pops the stack
  217. //-----------------------------------------------------------------------------
  218. template< class T, class M >
  219. void CUtlStack<T,M>::Pop()
  220. {
  221. assert( m_Size > 0 );
  222. Destruct( &Element(m_Size-1) );
  223. --m_Size;
  224. }
  225. template< class T, class M >
  226. void CUtlStack<T,M>::Pop( T& oldTop )
  227. {
  228. assert( m_Size > 0 );
  229. oldTop = Top();
  230. Pop();
  231. }
  232. template< class T, class M >
  233. void CUtlStack<T,M>::PopMultiple( int num )
  234. {
  235. assert( m_Size >= num );
  236. for ( int i = 0; i < num; ++i )
  237. Destruct( &Element( m_Size - i - 1 ) );
  238. m_Size -= num;
  239. }
  240. //-----------------------------------------------------------------------------
  241. // Element removal
  242. //-----------------------------------------------------------------------------
  243. template< class T, class M >
  244. void CUtlStack<T,M>::Clear()
  245. {
  246. for (int i = m_Size; --i >= 0; )
  247. Destruct(&Element(i));
  248. m_Size = 0;
  249. }
  250. //-----------------------------------------------------------------------------
  251. // Memory deallocation
  252. //-----------------------------------------------------------------------------
  253. template< class T, class M >
  254. void CUtlStack<T,M>::Purge()
  255. {
  256. Clear();
  257. m_Memory.Purge( );
  258. ResetDbgInfo();
  259. }
  260. #endif // UTLSTACK_H