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.

352 lines
6.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef __LIST_H__
  9. #define __LIST_H__
  10. // TODO:
  11. // GetPositionAtIndex needs to keep a cache of the previous call so
  12. // that it doesn't do a linear search every time.
  13. #include <stdlib.h>
  14. // FIXME: change the name of this to something more specific.
  15. typedef struct
  16. {
  17. } _Position;
  18. typedef _Position *Position;
  19. template <class T> class GList;
  20. template <class T> class GListIterator;
  21. // GListNode: Class decleration and definition
  22. template <class T> class GListNode
  23. {
  24. private:
  25. T data;
  26. GListNode<T> *next;
  27. GListNode<T> *prev;
  28. GListNode();
  29. GListNode( T item );
  30. friend class GList<T>;
  31. friend class GListIterator<T>;
  32. };
  33. template <class T>
  34. GListNode<T>::GListNode()
  35. {
  36. next = NULL;
  37. prev = NULL;
  38. }
  39. template <class T>
  40. GListNode<T>::GListNode( T item )
  41. {
  42. data = item;
  43. next = NULL;
  44. prev = NULL;
  45. }
  46. // GList: Class decleration and definition
  47. template <class T> class GList
  48. {
  49. public:
  50. // Contructors/destructors
  51. GList();
  52. //
  53. Position InsertAtHead( T );
  54. Position InsertAtTail( T );
  55. T Remove( Position position );
  56. void RemoveAll( void (*DeleteItem)( T ) );
  57. void RemoveSelectedItems( bool (*NeedsRemovalFunc)( T ), void (*DeleteItemFunc)( T ) );
  58. Position InsertAfter( T item, Position position );
  59. Position InsertBefore( T item, Position position );
  60. bool IsEmpty();
  61. int GetNumItems();
  62. T GetItemAtPosition( Position position );
  63. Position GetPositionAtIndex( int index );
  64. T GetItemAtIndex( int index );
  65. protected:
  66. GListNode<T> *head;
  67. GListNode<T> *tail;
  68. int numItems;
  69. friend class GListIterator<T>;
  70. };
  71. template<class T>
  72. GList<T>::GList()
  73. {
  74. // Set up a dummy head node and a dummy tail node.
  75. head = new GListNode<T>;
  76. tail = new GListNode<T>;
  77. head->next = tail;
  78. head->prev = head;
  79. tail->next = tail;
  80. tail->prev = head;
  81. numItems = 0;
  82. }
  83. template<class T>
  84. Position GList<T>::InsertAtHead( T item )
  85. {
  86. GListNode<T> *newNode = new GListNode<T>( item );
  87. head->next->prev = newNode;
  88. newNode->next = head->next;
  89. newNode->prev = head;
  90. head->next = newNode;
  91. numItems++;
  92. return ( Position )( void * )newNode;
  93. }
  94. template<class T>
  95. Position GList<T>::InsertAtTail( T item )
  96. {
  97. GListNode<T> *newNode = new GListNode<T>( item );
  98. tail->prev->next = newNode;
  99. newNode->prev = tail->prev;
  100. tail->prev = newNode;
  101. newNode->next = tail;
  102. numItems++;
  103. return ( Position )( void * )newNode;
  104. }
  105. template<class T>
  106. T GList<T>::Remove( Position position )
  107. {
  108. GListNode<T> *node = ( GListNode<T> * )( void * )position;
  109. node->prev->next = node->next;
  110. node->next->prev = node->prev;
  111. T data = node->data;
  112. numItems--;
  113. delete node;
  114. return data;
  115. }
  116. template<class T>
  117. void GList<T>::RemoveAll( void (*DeleteItemFunc)( T ) )
  118. {
  119. GListNode<T> *tmpNode;
  120. GListNode<T> *node = head->next;
  121. while( node != tail )
  122. {
  123. if( DeleteItemFunc )
  124. {
  125. DeleteItemFunc( node->data );
  126. }
  127. tmpNode = node->next;
  128. delete node;
  129. node = tmpNode;
  130. }
  131. head->next = tail;
  132. head->prev = head;
  133. tail->next = tail;
  134. tail->prev = head;
  135. numItems = 0;
  136. }
  137. template<class T>
  138. void GList<T>::RemoveSelectedItems( bool (*NeedsRemovalFunc)( T ), void (*DeleteItemFunc)( T ) )
  139. {
  140. GListNode<T> *tmpNode;
  141. GListNode<T> *node = head->next;
  142. while( node != tail )
  143. {
  144. if( NeedsRemovalFunc( node->data ) )
  145. {
  146. DeleteItemFunc( node->data );
  147. node->prev->next = node->next;
  148. node->next->prev = node->prev;
  149. tmpNode = node;
  150. node = node->next;
  151. delete tmpNode;
  152. numItems--;
  153. }
  154. else
  155. {
  156. node = node->next;
  157. }
  158. }
  159. }
  160. template<class T>
  161. Position GList<T>::InsertAfter( T item, Position position )
  162. {
  163. GListNode<T> *node = ( GListNode<T> * )( void * )position;
  164. GListNode<T> *newNode = new GListNode<T>( item );
  165. newNode->prev = node;
  166. newNode->next = node->next;
  167. node->next->prev = newNode;
  168. node->next = newNode;
  169. numItems++;
  170. return ( Position )( void * )newNode;
  171. }
  172. template<class T>
  173. Position GList<T>::InsertBefore( T item, Position position )
  174. {
  175. GListNode<T> *node = ( GListNode<T> * )( void * )position;
  176. GListNode<T> *newNode = new GListNode<T>( item );
  177. newNode->prev = node->prev;
  178. newNode->next = node;
  179. node->prev->next = newNode;
  180. node->prev = newNode;
  181. numItems++;
  182. return ( Position )( void * )newNode;
  183. }
  184. template<class T>
  185. bool GList<T>::IsEmpty()
  186. {
  187. return ( numItems == 0 );
  188. }
  189. template <class T>
  190. int GList<T>::GetNumItems()
  191. {
  192. return numItems;
  193. }
  194. template<class T>
  195. T GList<T>::GetItemAtPosition( Position position )
  196. {
  197. return ( ( GListNode<T> * )( void * )position )->data;
  198. }
  199. template<class T>
  200. Position GList<T>::GetPositionAtIndex( int index )
  201. {
  202. int i;
  203. GListNode<T> *node = head->next;
  204. for( i = 0; i < index; i++ )
  205. {
  206. node = node->next;
  207. }
  208. return ( Position )( void * )node;
  209. }
  210. template<class T>
  211. T GList<T>::GetItemAtIndex( int index )
  212. {
  213. return GetItemAtPosition( GetPositionAtIndex( index ) );
  214. }
  215. // GListIterator: Class decleration and definition
  216. template<class T> class GListIterator
  217. {
  218. public:
  219. GListIterator( GList<T> *GList );
  220. void GotoHead( void );
  221. void GotoTail( void );
  222. void Goto( int index );
  223. void Increment();
  224. void Decrement();
  225. T GetCurrentAndIncrement();
  226. T GetCurrentAndDecrement();
  227. T IncrementAndGetCurrent();
  228. T DecrementAndGetCurrent();
  229. // postfix
  230. T operator++( int ) { return GetCurrentAndIncrement(); }
  231. T operator--( int ) { return GetCurrentAndDecrement(); }
  232. // prefix
  233. T operator++() { return IncrementAndGetCurrent(); }
  234. T operator--() { return DecrementAndGetCurrent(); }
  235. T GetCurrent();
  236. bool AtEnd( void );
  237. bool AtBeginning( void );
  238. protected:
  239. GList<T> *list;
  240. GListNode<T> *currentNode;
  241. };
  242. template<class T>
  243. GListIterator<T>::GListIterator( GList<T> *list )
  244. {
  245. this->list = list;
  246. GotoHead();
  247. }
  248. template<class T>
  249. void GListIterator<T>::GotoHead()
  250. {
  251. this->currentNode = list->head->next;
  252. }
  253. template<class T>
  254. void GListIterator<T>::GotoTail()
  255. {
  256. this->currentNode = list->tail->prev;
  257. }
  258. template<class T>
  259. void GListIterator<T>::Goto( int index )
  260. {
  261. currentNode = ( GListNode<T> * )( void * )list->GetPositionAtIndex( index );
  262. }
  263. template<class T>
  264. void GListIterator<T>::Increment()
  265. {
  266. currentNode = currentNode->next;
  267. }
  268. template<class T>
  269. void GListIterator<T>::Decrement()
  270. {
  271. currentNode = currentNode->prev;
  272. }
  273. template<class T>
  274. T GListIterator<T>::GetCurrentAndIncrement()
  275. {
  276. T retval = currentNode->data;
  277. Increment();
  278. return retval;
  279. }
  280. template<class T>
  281. T GListIterator<T>::GetCurrentAndDecrement()
  282. {
  283. T retval = currentNode->data;
  284. Decrement();
  285. return retval;
  286. }
  287. template<class T>
  288. T GListIterator<T>::IncrementAndGetCurrent()
  289. {
  290. Increment();
  291. return GetCurrent();
  292. }
  293. template<class T>
  294. T GListIterator<T>::DecrementAndGetCurrent()
  295. {
  296. Decrement();
  297. return GetCurrent();
  298. }
  299. template<class T>
  300. T GListIterator<T>::GetCurrent()
  301. {
  302. return currentNode->data;
  303. }
  304. template<class T>
  305. bool GListIterator<T>::AtEnd( void )
  306. {
  307. return currentNode->next == currentNode;
  308. }
  309. template<class T>
  310. bool GListIterator<T>::AtBeginning( void )
  311. {
  312. return currentNode->prev == currentNode;
  313. }
  314. #endif /* __LIST_H__ */