Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

List.h 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /*!
  2. * \file include/List.h
  3. * \brief Template list
  4. *
  5. * UINT_MAX is an error condition, used in place of -1
  6. *
  7. * \author Mongoose
  8. * \author xythobuz
  9. */
  10. #ifndef _LIST_H_
  11. #define _LIST_H_
  12. #include <stdlib.h>
  13. #include <limits.h>
  14. #include <stdio.h>
  15. /*!
  16. * \brief Template class encapsulating a single list node
  17. * \tparam T encapsulated data type
  18. */
  19. template <class T> class ListNode {
  20. public:
  21. /*!
  22. * \brief Create a new ListNode
  23. * \param data Data to be stored in node
  24. * \param id node id
  25. */
  26. ListNode(T data, unsigned int id) {
  27. _data = data;
  28. _id = id;
  29. _next = NULL;
  30. }
  31. /*!
  32. * \brief Destroy a ListNode
  33. */
  34. ~ListNode() {
  35. }
  36. /*!
  37. * \brief Set the id of this ListNode
  38. * \param id new id
  39. */
  40. void Id(unsigned int id) {
  41. _id = id;
  42. }
  43. /*!
  44. * \brief Get the id of this ListNode
  45. * \returns current id
  46. */
  47. unsigned int Id() {
  48. return _id;
  49. }
  50. /*!
  51. * \brief Set the data of this ListNode
  52. * \param data new data
  53. */
  54. void Data(T data) {
  55. _data = data;
  56. }
  57. /*!
  58. * \brief Get the data of this ListNode
  59. * \returns current data
  60. */
  61. T Data() {
  62. return _data;
  63. }
  64. /*!
  65. * \brief Get the next ListNode in the List
  66. * \returns next pointer or NULL
  67. */
  68. ListNode<T> *Next() {
  69. return _next;
  70. }
  71. /*!
  72. * \brief Set the next ListNode in the List
  73. * \param next new next pointer
  74. */
  75. void Next(ListNode<T> *next) {
  76. _next = next;
  77. }
  78. /*!
  79. * \brief Print this ListNode
  80. */
  81. void Print() {
  82. printf("(%u, %p)", _id, _data);
  83. }
  84. private:
  85. ListNode<T> *_next; //!< Next Pointer
  86. unsigned int _id; //!< ListNode ID
  87. T _data; //!< Encapsulated data
  88. };
  89. /*!
  90. * \brief Template class representing a linked list
  91. * \tparam T encapsulated data type
  92. */
  93. template <class T> class List {
  94. public:
  95. /*!
  96. * \brief Construct a new linked list
  97. */
  98. List() {
  99. _num_items = 0;
  100. _head = NULL;
  101. _current = NULL;
  102. _last = NULL;
  103. _cache = NULL;
  104. }
  105. /*!
  106. * \brief Deconstruct a linked list
  107. * \sa List::Clear()
  108. */
  109. ~List() {
  110. Clear();
  111. }
  112. /*!
  113. * \brief Add all data from another list to this one
  114. * NOTE: this only copies data, the containers aren't the same ids
  115. * \param list source list where data does come from
  116. */
  117. void Copy(List<T> *list) {
  118. if (!list)
  119. return;
  120. for (list->Reset(); list->CurrentExists(); list->Next())
  121. Add(list->Current());
  122. }
  123. /*!
  124. * \brief Delete every item in this list
  125. */
  126. void Clear() {
  127. _num_items = 0;
  128. _last = _cache = NULL;
  129. while (_head) {
  130. _current = _head;
  131. _head = _head->Next();
  132. delete _current;
  133. }
  134. }
  135. /*!
  136. * \brief Searches the list for an id
  137. * \param id id to be searched
  138. * \returns data with id, or 0
  139. */
  140. T SearchId(unsigned int id) {
  141. ListNode<T> *current = _head;
  142. ListNode<T> *last = NULL;
  143. if (_cache) {
  144. if (id >= _cache->Id())
  145. current = _cache;
  146. }
  147. while (current) {
  148. // Found
  149. if (current->Id() == id) {
  150. _cache = current;
  151. return current->Data();
  152. }
  153. last = current;
  154. current = current->Next();
  155. }
  156. return 0;
  157. }
  158. /*!
  159. * \brief Searches the list for specific data
  160. * \param data data to be searched for
  161. * \returns id of data, or UINT_MAX
  162. */
  163. unsigned int SearchKey(T data) {
  164. ListNode<T> *current = _head;
  165. ListNode<T> *last = NULL;
  166. if (_cache) {
  167. // Mongoose: 2001-01-31, hhmmm... fixed?
  168. if (data == _cache->Data())
  169. return _cache->Id();
  170. }
  171. while (current) {
  172. // Found
  173. if (current->Data() == data) {
  174. _cache = current;
  175. return current->Id();
  176. }
  177. last = current;
  178. current = current->Next();
  179. }
  180. return UINT_MAX;
  181. }
  182. /*!
  183. * \brief Search for an id
  184. * \param i id to be searched
  185. * \returns id or 0
  186. * \sa List::SearchId()
  187. */
  188. T operator [] (unsigned int i) {
  189. if (_head) {
  190. return SearchId(i);
  191. } else {
  192. #ifdef DEBUG_INDEX_EMPTY_LIST
  193. printf("List[%u] = NULL\n", i);
  194. #endif
  195. }
  196. return 0;
  197. }
  198. /*!
  199. * \brief Search for an id and remove the associated item from the list
  200. * \param id id to be deleted
  201. */
  202. void RemoveId(unsigned int id) {
  203. ListNode<T> *current = _head;
  204. ListNode<T> *last = NULL;
  205. _last = _cache = NULL;
  206. while (current) {
  207. // Remove
  208. if (current->Id() == id) {
  209. if (current == _head)
  210. _head = current->Next();
  211. else
  212. last->Next(current->Next());
  213. if (_current == current)
  214. _current = NULL;
  215. delete current;
  216. _num_items--;
  217. return;
  218. }
  219. last = current;
  220. current = current->Next();
  221. }
  222. }
  223. /*!
  224. * \brief Search for data and remove the associated item from the list
  225. * \param data data to be deleted
  226. */
  227. void Remove(T data) {
  228. ListNode<T> *current = _head;
  229. ListNode<T> *last = NULL;
  230. _last = _cache = NULL;
  231. while (current) {
  232. // Remove
  233. if (current->Data() == data) {
  234. if (current == _head)
  235. _head = current->Next();
  236. else
  237. last->Next(current->Next());
  238. if (_current == current)
  239. _current = NULL;
  240. delete current;
  241. _num_items--;
  242. return;
  243. }
  244. last = current;
  245. current = current->Next();
  246. }
  247. }
  248. /*!
  249. * \brief Is the list empty?
  250. * \returns true if the list is empty
  251. */
  252. bool Empty() {
  253. return (_head == NULL);
  254. }
  255. /*!
  256. * \brief Length of the list
  257. * \returns number of items in the list
  258. */
  259. unsigned int NumItems() {
  260. return _num_items;
  261. }
  262. /*!
  263. * \brief Print the list
  264. * \param print_func function that will be called for each item in the list, after its id was printed. Or NULL.
  265. */
  266. void Print(void (*print_func)(T)) {
  267. ListNode<T> *current = _head;
  268. printf(" [%u] {\n", _num_items);
  269. while (current) {
  270. printf("#%u, ", current->Id());
  271. if (print_func)
  272. (*print_func)(current->Data());
  273. current = current->Next();
  274. fflush(stdout);
  275. }
  276. printf(" }\n");
  277. }
  278. /*!
  279. * \brief Print all IDs in this list
  280. */
  281. void Print() {
  282. ListNode<T> *current = _head;
  283. printf("List %u {\n", _num_items);
  284. while (current) {
  285. //current->Print();
  286. printf("%u", current->Id());
  287. current = current->Next();
  288. if (current)
  289. printf(", ");
  290. fflush(stdout);
  291. }
  292. printf(" }\n");
  293. }
  294. /*!
  295. * \brief Reset the iterator
  296. */
  297. void Reset() {
  298. _current = _head;
  299. _cache = _head;
  300. }
  301. /*!
  302. * \brief Traverses the list
  303. * \returns true if there is a new current item, false if the list is at the end
  304. * \sa List::Next()
  305. */
  306. bool operator ++ (int) {
  307. return Next();
  308. }
  309. /*!
  310. * \brief Traverses the list
  311. * \returns true if there is a new current item, false if the list is at the end
  312. * \sa List::Next()
  313. */
  314. bool operator ++ () {
  315. return Next();
  316. }
  317. /*!
  318. * \brief Traverses the list
  319. * \returns true if there is a new current item, false if the list is at the end
  320. */
  321. bool Next() {
  322. if (_current)
  323. _current = _current->Next();
  324. return (_current != NULL);
  325. }
  326. /*!
  327. * \brief Get the id of the current item
  328. * \returns id of current item or UINT_MAX if there is no current item
  329. */
  330. unsigned int CurrentId() {
  331. if (!_current)
  332. return UINT_MAX;
  333. return _current->Id();
  334. }
  335. /*!
  336. * \brief Is there a current item?
  337. * \returns true if there is a current item, false otherwise
  338. */
  339. bool CurrentExists() {
  340. return (_current != 0);
  341. }
  342. /*!
  343. * \brief Get the current items data
  344. * \returns data of the current item or 0 if there is no current item
  345. */
  346. T Current() {
  347. if (_current)
  348. return _current->Data();
  349. else
  350. return 0;
  351. }
  352. /*!
  353. * \brief Add data to the list. Constructs a new ListNode encapsulating the data.
  354. * \param data data to be stored
  355. * \returns id of the new ListNode
  356. */
  357. unsigned int Add(T data) {
  358. ListNode<T> *node;
  359. node = new ListNode<T>(data, _num_items++);
  360. return Add(node);
  361. }
  362. /*!
  363. * \brief Add a ListNode to the end of this List.
  364. * \param node new node
  365. * \returns id of the node
  366. */
  367. unsigned int Add(ListNode<T> *node) {
  368. ListNode<T> *current;
  369. ListNode<T> *last;
  370. unsigned int i;
  371. if (_head) {
  372. current = _head;
  373. last = NULL;
  374. i = 0;
  375. //EXP
  376. if (_last) {
  377. i = _last->Id();
  378. current = _last;
  379. }
  380. while (current) {
  381. // Prepend
  382. if (current->Id() > i) {
  383. node->Id(i);
  384. node->Next(current);
  385. if (current == _head)
  386. _head = node;
  387. else if (last)
  388. last->Next(node);
  389. return node->Id();
  390. }
  391. i++;
  392. last = current;
  393. current = current->Next();
  394. }
  395. // Append
  396. last->Next(node);
  397. } else
  398. _head = node;
  399. _last = node; //EXP
  400. return node->Id();
  401. }
  402. private:
  403. unsigned int _num_items; //!< Number of items in the list
  404. ListNode<T> *_head; //!< First item in the list
  405. ListNode<T> *_current; //!< Current item for the list iterator
  406. ListNode<T> *_last; //!< Last item in the list
  407. ListNode<T> *_cache; //!< cache used by the search methods
  408. };
  409. #endif