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.

295 lines
7.6 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Header: $
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #ifndef UTLMAP_H
  9. #define UTLMAP_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "tier0/dbg.h"
  14. #include "utlrbtree.h"
  15. //-----------------------------------------------------------------------------
  16. //
  17. // Purpose: An associative container. Pretty much identical to std::map.
  18. //
  19. //-----------------------------------------------------------------------------
  20. // This is a useful macro to iterate from start to end in order in a map
  21. #define FOR_EACH_MAP( mapName, iteratorName ) \
  22. for ( int iteratorName = (mapName).FirstInorder(); (mapName).IsUtlMap && iteratorName != (mapName).InvalidIndex(); iteratorName = (mapName).NextInorder( iteratorName ) )
  23. // faster iteration, but in an unspecified order
  24. #define FOR_EACH_MAP_FAST( mapName, iteratorName ) \
  25. for ( int iteratorName = 0; (mapName).IsUtlMap && iteratorName < (mapName).MaxElement(); ++iteratorName ) if ( !(mapName).IsValidIndex( iteratorName ) ) continue; else
  26. struct base_utlmap_t
  27. {
  28. public:
  29. // This enum exists so that FOR_EACH_MAP and FOR_EACH_MAP_FAST cannot accidentally
  30. // be used on a type that is not a CUtlMap. If the code compiles then all is well.
  31. // The check for IsUtlMap being true should be free.
  32. // Using an enum rather than a static const bool ensures that this trick works even
  33. // with optimizations disabled on gcc.
  34. enum { IsUtlMap = true };
  35. };
  36. template <typename K, typename T, typename I = unsigned short, typename LessFunc_t = bool (*)( const K &, const K & )>
  37. class CUtlMap : public base_utlmap_t
  38. {
  39. public:
  40. typedef K KeyType_t;
  41. typedef T ElemType_t;
  42. typedef I IndexType_t;
  43. // constructor, destructor
  44. // Left at growSize = 0, the memory will first allocate 1 element and double in size
  45. // at each increment.
  46. // LessFunc_t is required, but may be set after the constructor using SetLessFunc() below
  47. CUtlMap( int growSize = 0, int initSize = 0, const LessFunc_t &lessfunc = 0 )
  48. : m_Tree( growSize, initSize, CKeyLess( lessfunc ) )
  49. {
  50. }
  51. CUtlMap( LessFunc_t lessfunc )
  52. : m_Tree( CKeyLess( lessfunc ) )
  53. {
  54. }
  55. void EnsureCapacity( int num ) { m_Tree.EnsureCapacity( num ); }
  56. // gets particular elements
  57. ElemType_t & Element( IndexType_t i ) { return m_Tree.Element( i ).elem; }
  58. const ElemType_t & Element( IndexType_t i ) const { return m_Tree.Element( i ).elem; }
  59. ElemType_t & operator[]( IndexType_t i ) { return m_Tree.Element( i ).elem; }
  60. const ElemType_t & operator[]( IndexType_t i ) const { return m_Tree.Element( i ).elem; }
  61. KeyType_t & Key( IndexType_t i ) { return m_Tree.Element( i ).key; }
  62. const KeyType_t & Key( IndexType_t i ) const { return m_Tree.Element( i ).key; }
  63. // Num elements
  64. unsigned int Count() const { return m_Tree.Count(); }
  65. // Max "size" of the vector
  66. IndexType_t MaxElement() const { return m_Tree.MaxElement(); }
  67. // Checks if a node is valid and in the map
  68. bool IsValidIndex( IndexType_t i ) const { return m_Tree.IsValidIndex( i ); }
  69. // Checks if the map as a whole is valid
  70. bool IsValid() const { return m_Tree.IsValid(); }
  71. // Invalid index
  72. static IndexType_t InvalidIndex() { return CTree::InvalidIndex(); }
  73. // Sets the less func
  74. void SetLessFunc( LessFunc_t func )
  75. {
  76. m_Tree.SetLessFunc( CKeyLess( func ) );
  77. }
  78. // Insert method (inserts in order)
  79. IndexType_t Insert( const KeyType_t &key, const ElemType_t &insert )
  80. {
  81. Node_t node;
  82. node.key = key;
  83. node.elem = insert;
  84. return m_Tree.Insert( node );
  85. }
  86. IndexType_t Insert( const KeyType_t &key )
  87. {
  88. Node_t node;
  89. node.key = key;
  90. return m_Tree.Insert( node );
  91. }
  92. // API to macth src2 for Panormama
  93. // Note in src2 straight Insert() calls will assert on duplicates
  94. // Chosing not to take that change until discussed further
  95. IndexType_t InsertWithDupes( const KeyType_t &key, const ElemType_t &insert )
  96. {
  97. Node_t node;
  98. node.key = key;
  99. node.elem = insert;
  100. return m_Tree.Insert( node );
  101. }
  102. IndexType_t InsertWithDupes( const KeyType_t &key )
  103. {
  104. Node_t node;
  105. node.key = key;
  106. return m_Tree.Insert( node );
  107. }
  108. bool HasElement( const KeyType_t &key ) const
  109. {
  110. Node_t dummyNode;
  111. dummyNode.key = key;
  112. return m_Tree.HasElement( dummyNode );
  113. }
  114. // Find method
  115. IndexType_t Find( const KeyType_t &key ) const
  116. {
  117. Node_t dummyNode;
  118. dummyNode.key = key;
  119. return m_Tree.Find( dummyNode );
  120. }
  121. // FindFirst method
  122. // This finds the first inorder occurrence of key
  123. IndexType_t FindFirst( const KeyType_t &key ) const
  124. {
  125. Node_t dummyNode;
  126. dummyNode.key = key;
  127. return m_Tree.FindFirst( dummyNode );
  128. }
  129. const ElemType_t &FindElement( const KeyType_t &key, const ElemType_t &defaultValue ) const
  130. {
  131. IndexType_t i = Find( key );
  132. if ( i == InvalidIndex() )
  133. return defaultValue;
  134. return Element( i );
  135. }
  136. // First element >= key
  137. IndexType_t FindClosest( const KeyType_t &key, CompareOperands_t eFindCriteria ) const
  138. {
  139. Node_t dummyNode;
  140. dummyNode.key = key;
  141. return m_Tree.FindClosest( dummyNode, eFindCriteria );
  142. }
  143. // Remove methods
  144. void RemoveAt( IndexType_t i ) { m_Tree.RemoveAt( i ); }
  145. bool Remove( const KeyType_t &key )
  146. {
  147. Node_t dummyNode;
  148. dummyNode.key = key;
  149. return m_Tree.Remove( dummyNode );
  150. }
  151. void RemoveAll( ) { m_Tree.RemoveAll(); }
  152. void Purge( ) { m_Tree.Purge(); }
  153. // Purges the list and calls delete on each element in it.
  154. void PurgeAndDeleteElements();
  155. // Iteration
  156. IndexType_t FirstInorder() const { return m_Tree.FirstInorder(); }
  157. IndexType_t NextInorder( IndexType_t i ) const { return m_Tree.NextInorder( i ); }
  158. IndexType_t PrevInorder( IndexType_t i ) const { return m_Tree.PrevInorder( i ); }
  159. IndexType_t LastInorder() const { return m_Tree.LastInorder(); }
  160. // API Matching src2 for Panorama
  161. IndexType_t NextInorderSameKey( IndexType_t i ) const
  162. {
  163. IndexType_t iNext = NextInorder( i );
  164. if ( !IsValidIndex( iNext ) )
  165. return InvalidIndex();
  166. if ( Key( iNext ) != Key( i ) )
  167. return InvalidIndex();
  168. return iNext;
  169. }
  170. // If you change the search key, this can be used to reinsert the
  171. // element into the map.
  172. void Reinsert( const KeyType_t &key, IndexType_t i )
  173. {
  174. m_Tree[i].key = key;
  175. m_Tree.Reinsert(i);
  176. }
  177. IndexType_t InsertOrReplace( const KeyType_t &key, const ElemType_t &insert )
  178. {
  179. IndexType_t i = Find( key );
  180. if ( i != InvalidIndex() )
  181. {
  182. Element( i ) = insert;
  183. return i;
  184. }
  185. return Insert( key, insert );
  186. }
  187. void Swap( CUtlMap< K, T, I > &that )
  188. {
  189. m_Tree.Swap( that.m_Tree );
  190. }
  191. struct Node_t
  192. {
  193. Node_t()
  194. {
  195. }
  196. Node_t( const Node_t &from )
  197. : key( from.key ),
  198. elem( from.elem )
  199. {
  200. }
  201. KeyType_t key;
  202. ElemType_t elem;
  203. };
  204. class CKeyLess
  205. {
  206. public:
  207. CKeyLess( const LessFunc_t& lessFunc ) : m_LessFunc(lessFunc) {}
  208. bool operator!() const
  209. {
  210. return !m_LessFunc;
  211. }
  212. bool operator()( const Node_t &left, const Node_t &right ) const
  213. {
  214. return m_LessFunc( left.key, right.key );
  215. }
  216. LessFunc_t m_LessFunc;
  217. };
  218. typedef CUtlRBTree<Node_t, I, CKeyLess> CTree;
  219. CTree *AccessTree() { return &m_Tree; }
  220. protected:
  221. CTree m_Tree;
  222. };
  223. //-----------------------------------------------------------------------------
  224. // Purges the list and calls delete on each element in it.
  225. template< typename K, typename T, typename I, typename LessFunc_t >
  226. inline void CUtlMap<K, T, I, LessFunc_t>::PurgeAndDeleteElements()
  227. {
  228. for ( I i = 0; i < MaxElement(); ++i )
  229. {
  230. if ( !IsValidIndex( i ) )
  231. continue;
  232. delete Element( i );
  233. }
  234. Purge();
  235. }
  236. #endif // UTLMAP_H