Open Source Tomb Raider Engine
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.

List.h 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : Freyja
  5. * Author : Mongoose
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : List
  9. * License : No use w/o permission (C) 2000 Mongoose
  10. * Comments: mtk Template list
  11. *
  12. * UINT_MAX is an error condition, used in place of -1
  13. *
  14. * This file was generated using Mongoose's C++
  15. * template generator script. <stu7440@westga.edu>
  16. *
  17. *-- History ------------------------------------------------
  18. *
  19. * 2000-10-26:
  20. * Mongoose - Created
  21. ================================================================*/
  22. #ifndef __FREYJA_MONGOOSE_LIST_H_
  23. #define __FREYJA_MONGOOSE_LIST_H_
  24. #include <stdlib.h>
  25. #include <limits.h>
  26. #include <stdio.h>
  27. #ifdef DEBUG_MEMORY
  28. #include <memory_test.h>
  29. #endif
  30. template <class T> class ListNode
  31. {
  32. public:
  33. ListNode(T data, unsigned int id)
  34. {
  35. _data = data;
  36. _id = id;
  37. _next = NULL;
  38. }
  39. ~ListNode()
  40. {
  41. }
  42. void Id(unsigned int id)
  43. {
  44. _id = id;
  45. }
  46. unsigned int Id()
  47. {
  48. return _id;
  49. }
  50. void Data(T data)
  51. {
  52. _data = data;
  53. }
  54. T Data()
  55. {
  56. return _data;
  57. }
  58. ListNode<T> *Next()
  59. {
  60. return _next;
  61. }
  62. void Next(ListNode<T> *next)
  63. {
  64. _next = next;
  65. }
  66. void Print()
  67. {
  68. //printf("(%i, %p)", _id, _data);
  69. printf("%i", _id);
  70. }
  71. private:
  72. ListNode<T> *_next;
  73. unsigned int _id;
  74. T _data;
  75. };
  76. template <class T> class List
  77. {
  78. public:
  79. List()
  80. {
  81. _num_items = 0;
  82. _head = NULL;
  83. _current = NULL;
  84. _last = NULL;
  85. _cache = NULL;
  86. }
  87. ~List()
  88. {
  89. Clear();
  90. }
  91. // NOTE: this only copies data, the containers aren't the same ids
  92. void Copy(List<T> *list)
  93. {
  94. if (!list)
  95. return;
  96. for (list->Reset(); list->CurrentExists(); list->Next())
  97. Add(list->Current());
  98. }
  99. void Clear()
  100. {
  101. _num_items = 0;
  102. _last = _cache = NULL;
  103. while (_head)
  104. {
  105. _current = _head;
  106. _head = _head->Next();
  107. delete _current;
  108. }
  109. }
  110. T SearchId(unsigned int id)
  111. {
  112. ListNode<T> *current = _head;
  113. ListNode<T> *last = NULL;
  114. if (_cache)
  115. {
  116. if (id >= _cache->Id())
  117. current = _cache;
  118. }
  119. while (current)
  120. {
  121. // Found
  122. if (current->Id() == id)
  123. {
  124. _cache = current;
  125. return current->Data();
  126. }
  127. last = current;
  128. current = current->Next();
  129. }
  130. return 0;
  131. }
  132. unsigned int SearchKey(T data)
  133. {
  134. ListNode<T> *current = _head;
  135. ListNode<T> *last = NULL;
  136. if (_cache)
  137. {
  138. // Mongoose: 2001-01-31, hhmmm... fixed?
  139. if (data == _cache->Data())
  140. return _cache->Id();
  141. }
  142. while (current)
  143. {
  144. // Found
  145. if (current->Data() == data)
  146. {
  147. _cache = current;
  148. return current->Id();
  149. }
  150. last = current;
  151. current = current->Next();
  152. }
  153. return UINT_MAX;
  154. }
  155. T operator [] (unsigned int i)
  156. {
  157. if (_head)
  158. {
  159. return SearchId(i);
  160. }
  161. else
  162. {
  163. #ifdef DEBUG_INDEX_EMPTY_LIST
  164. printf("List[%i] = NULL\n", i);
  165. #endif
  166. }
  167. return 0;
  168. }
  169. void RemoveId(unsigned int id)
  170. {
  171. ListNode<T> *current = _head;
  172. ListNode<T> *last = NULL;
  173. _last = _cache = NULL;
  174. while (current)
  175. {
  176. // Remove
  177. if (current->Id() == id)
  178. {
  179. if (current == _head)
  180. _head = current->Next();
  181. else
  182. {
  183. last->Next(current->Next());
  184. }
  185. if (_current == current)
  186. _current = NULL;
  187. delete current;
  188. _num_items--;
  189. return;
  190. }
  191. last = current;
  192. current = current->Next();
  193. }
  194. }
  195. void Remove(T data)
  196. {
  197. ListNode<T> *current = _head;
  198. ListNode<T> *last = NULL;
  199. _last = _cache = NULL;
  200. while (current)
  201. {
  202. // Remove
  203. if (current->Data() == data)
  204. {
  205. if (current == _head)
  206. _head = current->Next();
  207. else
  208. {
  209. last->Next(current->Next());
  210. }
  211. if (_current == current)
  212. _current = NULL;
  213. delete current;
  214. _num_items--;
  215. return;
  216. }
  217. last = current;
  218. current = current->Next();
  219. }
  220. }
  221. bool Empty()
  222. {
  223. return (_head == NULL);
  224. }
  225. unsigned int NumItems()
  226. {
  227. return _num_items;
  228. }
  229. void Print(void (*print_func)(T))
  230. {
  231. ListNode<T> *current = _head;
  232. printf(" [%i] {\n", _num_items);
  233. while (current)
  234. {
  235. printf("#%i, ", current->Id());
  236. if (print_func)
  237. (*print_func)(current->Data());
  238. current = current->Next();
  239. fflush(stdout);
  240. }
  241. printf(" }\n");
  242. }
  243. void Print()
  244. {
  245. ListNode<T> *current = _head;
  246. printf("List %i {\n", _num_items);
  247. while (current)
  248. {
  249. //current->Print();
  250. printf("%i", current->Id());
  251. current = current->Next();
  252. if (current)
  253. printf(", ");
  254. fflush(stdout);
  255. }
  256. printf(" }\n");
  257. }
  258. void Reset()
  259. {
  260. _current = _head;
  261. _cache = _head;
  262. }
  263. bool operator ++ (int dummy)
  264. {
  265. return Next();
  266. }
  267. bool Next()
  268. {
  269. if (_current)
  270. _current = _current->Next();
  271. return (_current != NULL);
  272. }
  273. unsigned int CurrentId()
  274. {
  275. if (!_current)
  276. return UINT_MAX;
  277. return _current->Id();
  278. }
  279. bool CurrentExists()
  280. {
  281. return (_current != 0);
  282. }
  283. T Current()
  284. {
  285. if (_current)
  286. return _current->Data();
  287. else
  288. return 0;
  289. }
  290. unsigned int Add(T data)
  291. {
  292. ListNode<T> *node;
  293. node = new ListNode<T>(data, _num_items++);
  294. return Add(node);
  295. }
  296. unsigned int Add(ListNode<T> *node)
  297. {
  298. ListNode<T> *current;
  299. ListNode<T> *last;
  300. unsigned int i;
  301. if (_head)
  302. {
  303. current = _head;
  304. last = NULL;
  305. i = 0;
  306. //EXP
  307. if (_last)
  308. {
  309. i = _last->Id();
  310. current = _last;
  311. }
  312. while (current)
  313. {
  314. // Prepend
  315. if (current->Id() > i)
  316. {
  317. node->Id(i);
  318. node->Next(current);
  319. if (current == _head)
  320. _head = node;
  321. else if (last)
  322. last->Next(node);
  323. return node->Id();
  324. }
  325. i++;
  326. last = current;
  327. current = current->Next();
  328. }
  329. // Append
  330. last->Next(node);
  331. }
  332. else
  333. _head = node;
  334. _last = node; //EXP
  335. return node->Id();
  336. }
  337. private:
  338. unsigned int _num_items;
  339. ListNode<T> *_head;
  340. ListNode<T> *_current;
  341. ListNode<T> *_last;
  342. ListNode<T> *_cache;
  343. };
  344. #endif