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.

332 lines
8.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. // A growable array class that maintains a free list and keeps elements
  8. // in the same location
  9. //=============================================================================//
  10. #ifndef UTLARRAY_H
  11. #define UTLARRAY_H
  12. #ifdef _WIN32
  13. #pragma once
  14. #endif
  15. #include "tier0/platform.h"
  16. #include "tier0/dbg.h"
  17. #include "vstdlib/random.h"
  18. #define FOR_EACH_ARRAY( vecName, iteratorName ) \
  19. for ( int iteratorName = 0; (vecName).IsUtlArray && iteratorName < (vecName).Count(); iteratorName++ )
  20. #define FOR_EACH_ARRAY_BACK( vecName, iteratorName ) \
  21. for ( int iteratorName = (vecName).Count()-1; (vecName).IsUtlArray && iteratorName >= 0; iteratorName-- )
  22. // utlarray derives from this so we can do the type check above
  23. struct base_array_t
  24. {
  25. public:
  26. static const bool IsUtlArray = true; // Used to match this at compiletime
  27. };
  28. #if defined( GNUC ) && defined( DEBUG )
  29. // gcc in debug doesn't optimize away the need for the storage of IsUtlArray so make one here
  30. // as this is in a shared header use SELECTANY to make it throw away the dupe symbols
  31. const bool base_array_t::IsUtlArray SELECTANY;
  32. #endif
  33. //-----------------------------------------------------------------------------
  34. template< class T, size_t MAX_SIZE >
  35. class CUtlArray : public base_array_t
  36. {
  37. public:
  38. typedef T ElemType_t;
  39. typedef T* iterator;
  40. typedef const T* const_iterator;
  41. CUtlArray();
  42. CUtlArray( T* pMemory, size_t count );
  43. ~CUtlArray();
  44. CUtlArray<T, MAX_SIZE>& operator=( const CUtlArray<T, MAX_SIZE> &other );
  45. CUtlArray( CUtlArray const& vec );
  46. // element access
  47. T& operator[]( int i );
  48. const T& operator[]( int i ) const;
  49. T& Element( int i );
  50. const T& Element( int i ) const;
  51. T& Random();
  52. const T& Random() const;
  53. // STL compatible member functions. These allow easier use of std::sort
  54. // and they are forward compatible with the C++ 11 range-based for loops.
  55. iterator begin();
  56. const_iterator begin() const;
  57. iterator end();
  58. const_iterator end() const;
  59. T* Base();
  60. const T* Base() const;
  61. // Returns the number of elements in the array, NumAllocated() is included for consistency with UtlVector
  62. int Count() const;
  63. int NumAllocated() const;
  64. // Is element index valid?
  65. bool IsValidIndex( int i ) const;
  66. static int InvalidIndex();
  67. void CopyArray( const T *pArray, size_t count );
  68. void Swap( CUtlArray< T, MAX_SIZE > &vec );
  69. // Finds an element (element needs operator== defined)
  70. int Find( const T& src ) const;
  71. void FillWithValue( const T& src );
  72. bool HasElement( const T& src ) const;
  73. // calls delete on each element in it.
  74. void DeleteElements();
  75. void Sort( int (__cdecl *pfnCompare)(const T *, const T *) );
  76. protected:
  77. T m_Memory[ MAX_SIZE ];
  78. };
  79. //-----------------------------------------------------------------------------
  80. // constructor, destructor
  81. //-----------------------------------------------------------------------------
  82. template< typename T, size_t MAX_SIZE >
  83. inline CUtlArray<T, MAX_SIZE>::CUtlArray()
  84. {
  85. }
  86. template< typename T, size_t MAX_SIZE >
  87. inline CUtlArray<T, MAX_SIZE>::CUtlArray( T* pMemory, size_t count )
  88. {
  89. CopyArray( pMemory, count );
  90. }
  91. template< typename T, size_t MAX_SIZE >
  92. inline CUtlArray<T, MAX_SIZE>::~CUtlArray()
  93. {
  94. }
  95. template< typename T, size_t MAX_SIZE >
  96. inline CUtlArray<T, MAX_SIZE>& CUtlArray<T, MAX_SIZE>::operator=( const CUtlArray<T, MAX_SIZE> &other )
  97. {
  98. if ( this != &other )
  99. {
  100. for ( size_t n = 0; n < MAX_SIZE; ++n )
  101. {
  102. m_Memory[n] = other.m_Memory[n];
  103. }
  104. }
  105. return *this;
  106. }
  107. template< typename T, size_t MAX_SIZE >
  108. inline CUtlArray<T, MAX_SIZE>::CUtlArray( CUtlArray const& vec )
  109. {
  110. for ( size_t n = 0; n < MAX_SIZE; ++n )
  111. {
  112. m_Memory[n] = vec.m_Memory[n];
  113. }
  114. }
  115. template< typename T, size_t MAX_SIZE >
  116. typename CUtlArray<T, MAX_SIZE>::iterator CUtlArray<T, MAX_SIZE>::begin()
  117. {
  118. return Base();
  119. }
  120. template< typename T, size_t MAX_SIZE >
  121. typename CUtlArray<T, MAX_SIZE>::const_iterator CUtlArray<T, MAX_SIZE>::begin() const
  122. {
  123. return Base();
  124. }
  125. template< typename T, size_t MAX_SIZE >
  126. typename CUtlArray<T, MAX_SIZE>::iterator CUtlArray<T, MAX_SIZE>::end()
  127. {
  128. return Base() + Count();
  129. }
  130. template< typename T, size_t MAX_SIZE >
  131. typename CUtlArray<T, MAX_SIZE>::const_iterator CUtlArray<T, MAX_SIZE>::end() const
  132. {
  133. return Base() + Count();
  134. }
  135. template< typename T, size_t MAX_SIZE >
  136. inline T *CUtlArray<T, MAX_SIZE>::Base()
  137. {
  138. return &m_Memory[0];
  139. }
  140. template< typename T, size_t MAX_SIZE >
  141. inline const T *CUtlArray<T, MAX_SIZE>::Base() const
  142. {
  143. return &m_Memory[0];
  144. }
  145. //-----------------------------------------------------------------------------
  146. // element access
  147. //-----------------------------------------------------------------------------
  148. template< typename T, size_t MAX_SIZE >
  149. inline T& CUtlArray<T, MAX_SIZE>::operator[]( int i )
  150. {
  151. Assert( IsValidIndex( i ) );
  152. return m_Memory[ i ];
  153. }
  154. template< typename T, size_t MAX_SIZE >
  155. inline const T& CUtlArray<T, MAX_SIZE>::operator[]( int i ) const
  156. {
  157. Assert( IsValidIndex( i ) );
  158. return m_Memory[ i ];
  159. }
  160. template< typename T, size_t MAX_SIZE >
  161. inline T& CUtlArray<T, MAX_SIZE>::Element( int i )
  162. {
  163. Assert( IsValidIndex( i ) );
  164. return m_Memory[ i ];
  165. }
  166. template< typename T, size_t MAX_SIZE >
  167. inline const T& CUtlArray<T, MAX_SIZE>::Element( int i ) const
  168. {
  169. Assert( IsValidIndex( i ) );
  170. return m_Memory[ i ];
  171. }
  172. template< typename T, size_t MAX_SIZE >
  173. inline T& CUtlArray<T, MAX_SIZE>::Random()
  174. {
  175. Assert( MAX_SIZE > 0 );
  176. return m_Memory[ RandomInt( 0, MAX_SIZE - 1 ) ];
  177. }
  178. template< typename T, size_t MAX_SIZE >
  179. inline const T& CUtlArray<T, MAX_SIZE>::Random() const
  180. {
  181. Assert( MAX_SIZE > 0 );
  182. return m_Memory[ RandomInt( 0, MAX_SIZE - 1 ) ];
  183. }
  184. //-----------------------------------------------------------------------------
  185. // Count
  186. //-----------------------------------------------------------------------------
  187. template< typename T, size_t MAX_SIZE >
  188. inline int CUtlArray<T, MAX_SIZE>::Count() const
  189. {
  190. return (int)MAX_SIZE;
  191. }
  192. //-----------------------------------------------------------------------------
  193. template< typename T, size_t MAX_SIZE >
  194. inline int CUtlArray<T, MAX_SIZE>::NumAllocated() const
  195. {
  196. return (int)MAX_SIZE;
  197. }
  198. //-----------------------------------------------------------------------------
  199. // Is element index valid?
  200. //-----------------------------------------------------------------------------
  201. template< typename T, size_t MAX_SIZE >
  202. inline bool CUtlArray<T, MAX_SIZE>::IsValidIndex( int i ) const
  203. {
  204. return (i >= 0) && (i < MAX_SIZE);
  205. }
  206. //-----------------------------------------------------------------------------
  207. // Returns in invalid index
  208. //-----------------------------------------------------------------------------
  209. template< typename T, size_t MAX_SIZE >
  210. inline int CUtlArray<T, MAX_SIZE>::InvalidIndex()
  211. {
  212. return -1;
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Sorts the vector
  216. //-----------------------------------------------------------------------------
  217. template< typename T, size_t MAX_SIZE >
  218. void CUtlArray<T, MAX_SIZE>::Sort( int (__cdecl *pfnCompare)(const T *, const T *) )
  219. {
  220. typedef int (__cdecl *QSortCompareFunc_t)(const void *, const void *);
  221. if ( Count() <= 1 )
  222. return;
  223. qsort( Base(), Count(), sizeof(T), (QSortCompareFunc_t)(pfnCompare) );
  224. }
  225. template< typename T, size_t MAX_SIZE >
  226. void CUtlArray<T, MAX_SIZE>::CopyArray( const T *pArray, size_t count )
  227. {
  228. Assert( count < MAX_SIZE );
  229. for ( size_t n = 0; n < count; ++n )
  230. {
  231. m_Memory[n] = pArray[n];
  232. }
  233. }
  234. template< typename T, size_t MAX_SIZE >
  235. void CUtlArray<T, MAX_SIZE>::Swap( CUtlArray< T, MAX_SIZE > &vec )
  236. {
  237. for ( size_t n = 0; n < MAX_SIZE; ++n )
  238. {
  239. V_swap( m_Memory[n], vec.m_Memory[n] );
  240. }
  241. }
  242. //-----------------------------------------------------------------------------
  243. // Finds an element (element needs operator== defined)
  244. //-----------------------------------------------------------------------------
  245. template< typename T, size_t MAX_SIZE >
  246. int CUtlArray<T, MAX_SIZE>::Find( const T& src ) const
  247. {
  248. for ( int i = 0; i < Count(); ++i )
  249. {
  250. if (Element(i) == src)
  251. return i;
  252. }
  253. return -1;
  254. }
  255. template< typename T, size_t MAX_SIZE >
  256. void CUtlArray<T, MAX_SIZE>::FillWithValue( const T& src )
  257. {
  258. for ( int i = 0; i < Count(); i++ )
  259. {
  260. Element(i) = src;
  261. }
  262. }
  263. template< typename T, size_t MAX_SIZE >
  264. bool CUtlArray<T, MAX_SIZE>::HasElement( const T& src ) const
  265. {
  266. return ( Find(src) >= 0 );
  267. }
  268. template< typename T, size_t MAX_SIZE >
  269. inline void CUtlArray<T, MAX_SIZE>::DeleteElements()
  270. {
  271. for( int i=0; i < MAX_SIZE; i++ )
  272. {
  273. delete Element(i);
  274. }
  275. }
  276. #endif // UTLARRAY_H