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.

365 lines
10 KiB

  1. //====== Copyright � 1996-2005, Valve Corporation, All rights reserved. =======//
  2. //
  3. // Purpose: A dictionary mapping from symbol to structure
  4. //
  5. // $Header: $
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #ifndef UTLDICT_H
  9. #define UTLDICT_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "tier0/dbg.h"
  14. #include "tier1/utlmap.h"
  15. // Include this because tons of code was implicitly getting utlsymbol or utlvector via utldict.h
  16. #include "tier1/utlsymbol.h"
  17. #include "tier0/memdbgon.h"
  18. enum EDictCompareType
  19. {
  20. k_eDictCompareTypeCaseSensitive=0,
  21. k_eDictCompareTypeCaseInsensitive=1,
  22. k_eDictCompareTypeFilenames // Slashes and backslashes count as the same character..
  23. };
  24. //-----------------------------------------------------------------------------
  25. // A dictionary mapping from symbol to structure
  26. //-----------------------------------------------------------------------------
  27. // This is a useful macro to iterate from start to end in order in a map
  28. #define FOR_EACH_DICT( dictName, iteratorName ) \
  29. for( int iteratorName=dictName.First(); iteratorName != dictName.InvalidIndex(); iteratorName = dictName.Next( iteratorName ) )
  30. // faster iteration, but in an unspecified order
  31. #define FOR_EACH_DICT_FAST( dictName, iteratorName ) \
  32. for ( int iteratorName = 0; iteratorName < dictName.MaxElement(); ++iteratorName ) if ( !dictName.IsValidIndex( iteratorName ) ) continue; else
  33. //-----------------------------------------------------------------------------
  34. // A dictionary mapping from symbol to structure
  35. //-----------------------------------------------------------------------------
  36. template <class T, class I = int >
  37. class CUtlDict
  38. {
  39. public:
  40. typedef const char* KeyType_t;
  41. typedef T ElemType_t;
  42. // constructor, destructor
  43. // Left at growSize = 0, the memory will first allocate 1 element and double in size
  44. // at each increment.
  45. CUtlDict( int compareType = k_eDictCompareTypeCaseInsensitive, int growSize = 0, int initSize = 0 );
  46. ~CUtlDict( );
  47. void EnsureCapacity( int );
  48. // gets particular elements
  49. T& Element( I i );
  50. const T& Element( I i ) const;
  51. T& operator[]( I i );
  52. const T& operator[]( I i ) const;
  53. // gets element names
  54. //char *GetElementName( I i );
  55. char const *GetElementName( I i ) const;
  56. void SetElementName( I i, char const *pName );
  57. // Number of elements
  58. unsigned int Count() const;
  59. // Number of allocated slots
  60. I MaxElement() const;
  61. // Checks if a node is valid and in the tree
  62. bool IsValidIndex( I i ) const;
  63. // Invalid index
  64. static I InvalidIndex();
  65. // Insert method (inserts in order)
  66. I Insert( const char *pName, const T &element );
  67. I Insert( const char *pName );
  68. // Find method
  69. I Find( const char *pName ) const;
  70. bool HasElement( const char *pName ) const;
  71. // Remove methods
  72. void RemoveAt( I i );
  73. void Remove( const char *pName );
  74. void RemoveAll( );
  75. // Purge memory
  76. void Purge();
  77. void PurgeAndDeleteElements(); // Call delete on each element.
  78. // Iteration methods
  79. I First() const;
  80. I Next( I i ) const;
  81. // Nested typedefs, for code that might need
  82. // to fish out the index type from a given dict
  83. typedef I IndexType_t;
  84. protected:
  85. typedef CUtlMap<const char *, T, I> DictElementMap_t;
  86. DictElementMap_t m_Elements;
  87. };
  88. //-----------------------------------------------------------------------------
  89. // constructor, destructor
  90. //-----------------------------------------------------------------------------
  91. template <class T, class I>
  92. CUtlDict<T, I>::CUtlDict( int compareType, int growSize, int initSize ) : m_Elements( growSize, initSize )
  93. {
  94. if ( compareType == k_eDictCompareTypeFilenames )
  95. {
  96. m_Elements.SetLessFunc( CaselessStringLessThanIgnoreSlashes );
  97. }
  98. else if ( compareType == k_eDictCompareTypeCaseInsensitive )
  99. {
  100. m_Elements.SetLessFunc( CaselessStringLessThan );
  101. }
  102. else
  103. {
  104. m_Elements.SetLessFunc( StringLessThan );
  105. }
  106. }
  107. template <class T, class I>
  108. CUtlDict<T, I>::~CUtlDict()
  109. {
  110. Purge();
  111. }
  112. template <class T, class I>
  113. inline void CUtlDict<T, I>::EnsureCapacity( int num )
  114. {
  115. return m_Elements.EnsureCapacity( num );
  116. }
  117. //-----------------------------------------------------------------------------
  118. // gets particular elements
  119. //-----------------------------------------------------------------------------
  120. template <class T, class I>
  121. inline T& CUtlDict<T, I>::Element( I i )
  122. {
  123. return m_Elements[i];
  124. }
  125. template <class T, class I>
  126. inline const T& CUtlDict<T, I>::Element( I i ) const
  127. {
  128. return m_Elements[i];
  129. }
  130. //-----------------------------------------------------------------------------
  131. // gets element names
  132. //-----------------------------------------------------------------------------
  133. /*template <class T, class I>
  134. inline char *CUtlDict<T, I>::GetElementName( I i )
  135. {
  136. return const_cast< char* >( m_Elements.Key( i ) );
  137. }*/
  138. template <class T, class I>
  139. inline char const *CUtlDict<T, I>::GetElementName( I i ) const
  140. {
  141. return m_Elements.Key( i );
  142. }
  143. template <class T, class I>
  144. inline T& CUtlDict<T, I>::operator[]( I i )
  145. {
  146. return Element(i);
  147. }
  148. template <class T, class I>
  149. inline const T & CUtlDict<T, I>::operator[]( I i ) const
  150. {
  151. return Element(i);
  152. }
  153. template <class T, class I>
  154. inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
  155. {
  156. MEM_ALLOC_CREDIT_CLASS();
  157. // TODO: This makes a copy of the old element
  158. // TODO: This relies on the rb tree putting the most recently
  159. // removed element at the head of the insert list
  160. free( const_cast< char* >( m_Elements.Key( i ) ) );
  161. m_Elements.Reinsert( strdup( pName ), i );
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Num elements
  165. //-----------------------------------------------------------------------------
  166. template <class T, class I>
  167. inline unsigned int CUtlDict<T, I>::Count() const
  168. {
  169. return m_Elements.Count();
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Number of allocated slots
  173. //-----------------------------------------------------------------------------
  174. template <class T, class I>
  175. inline I CUtlDict<T, I>::MaxElement() const
  176. {
  177. return m_Elements.MaxElement();
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Checks if a node is valid and in the tree
  181. //-----------------------------------------------------------------------------
  182. template <class T, class I>
  183. inline bool CUtlDict<T, I>::IsValidIndex( I i ) const
  184. {
  185. return m_Elements.IsValidIndex(i);
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Invalid index
  189. //-----------------------------------------------------------------------------
  190. template <class T, class I>
  191. inline I CUtlDict<T, I>::InvalidIndex()
  192. {
  193. return DictElementMap_t::InvalidIndex();
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Delete a node from the tree
  197. //-----------------------------------------------------------------------------
  198. template <class T, class I>
  199. void CUtlDict<T, I>::RemoveAt(I elem)
  200. {
  201. free( const_cast< char* >( m_Elements.Key( elem ) ) );
  202. m_Elements.RemoveAt(elem);
  203. }
  204. //-----------------------------------------------------------------------------
  205. // remove a node in the tree
  206. //-----------------------------------------------------------------------------
  207. template <class T, class I> void CUtlDict<T, I>::Remove( const char *search )
  208. {
  209. I node = Find( search );
  210. if (node != InvalidIndex())
  211. {
  212. RemoveAt(node);
  213. }
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Removes all nodes from the tree
  217. //-----------------------------------------------------------------------------
  218. template <class T, class I>
  219. void CUtlDict<T, I>::RemoveAll()
  220. {
  221. typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder();
  222. while ( index != m_Elements.InvalidIndex() )
  223. {
  224. const char* p = m_Elements.Key( index );
  225. free( const_cast< char* >( p ) );
  226. index = m_Elements.NextInorder( index );
  227. }
  228. m_Elements.RemoveAll();
  229. }
  230. template <class T, class I>
  231. void CUtlDict<T, I>::Purge()
  232. {
  233. RemoveAll();
  234. }
  235. template <class T, class I>
  236. void CUtlDict<T, I>::PurgeAndDeleteElements()
  237. {
  238. // Delete all the elements.
  239. I index = m_Elements.FirstInorder();
  240. while ( index != m_Elements.InvalidIndex() )
  241. {
  242. const char* p = m_Elements.Key( index );
  243. free( const_cast< char* >( p ) );
  244. delete m_Elements[index];
  245. index = m_Elements.NextInorder( index );
  246. }
  247. m_Elements.RemoveAll();
  248. }
  249. //-----------------------------------------------------------------------------
  250. // inserts a node into the tree
  251. //-----------------------------------------------------------------------------
  252. template <class T, class I>
  253. I CUtlDict<T, I>::Insert( const char *pName, const T &element )
  254. {
  255. MEM_ALLOC_CREDIT_CLASS();
  256. return m_Elements.Insert( strdup( pName ), element );
  257. }
  258. template <class T, class I>
  259. I CUtlDict<T, I>::Insert( const char *pName )
  260. {
  261. MEM_ALLOC_CREDIT_CLASS();
  262. return m_Elements.Insert( strdup( pName ) );
  263. }
  264. //-----------------------------------------------------------------------------
  265. // finds a node in the tree
  266. //-----------------------------------------------------------------------------
  267. template <class T, class I>
  268. I CUtlDict<T, I>::Find( const char *pName ) const
  269. {
  270. MEM_ALLOC_CREDIT_CLASS();
  271. if ( pName )
  272. return m_Elements.Find( pName );
  273. else
  274. return InvalidIndex();
  275. }
  276. //-----------------------------------------------------------------------------
  277. // returns true if we already have this node
  278. //-----------------------------------------------------------------------------
  279. template <class T, class I>
  280. bool CUtlDict<T, I>::HasElement( const char *pName ) const
  281. {
  282. if ( pName )
  283. return m_Elements.IsValidIndex( m_Elements.Find( pName ) );
  284. else
  285. return false;
  286. }
  287. //-----------------------------------------------------------------------------
  288. // Iteration methods
  289. //-----------------------------------------------------------------------------
  290. template <class T, class I>
  291. I CUtlDict<T, I>::First() const
  292. {
  293. return m_Elements.FirstInorder();
  294. }
  295. template <class T, class I>
  296. I CUtlDict<T, I>::Next( I i ) const
  297. {
  298. return m_Elements.NextInorder(i);
  299. }
  300. #include "tier0/memdbgoff.h"
  301. #endif // UTLDICT_H