linkedList.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef LLIST_H
  23. #define LLIST_H
  24. //***************************************************************************************
  25. // Linked List
  26. //***************************************************************************************
  27. // This template has an overhead of size LListNode for each entry in the linked list -
  28. // be aware of this for very large linked lists.
  29. //
  30. // This template has no destructor! You must explicitly call free() if you want the
  31. // contents of the list to be destroyed.
  32. //
  33. //
  34. // WARNING - this template has not been thoroughly tested so there may be bugs in it!
  35. //
  36. // -Bramage
  37. //---------------------------------------------------------------------------------------
  38. //---------------------------------------------------------------------------------------
  39. // LListNode template data node
  40. //---------------------------------------------------------------------------------------
  41. template <class T> class LListNode
  42. {
  43. public:
  44. LListNode<T> * Next;
  45. LListNode<T> * Prev;
  46. T * Data;
  47. LListNode()
  48. {
  49. Next = NULL;
  50. Prev = NULL;
  51. Data = NULL;
  52. }
  53. };
  54. //---------------------------------------------------------------------------------------
  55. // LList template
  56. //---------------------------------------------------------------------------------------
  57. template <class T> class LList
  58. {
  59. protected:
  60. LListNode< T > *first_entry;
  61. LListNode< T > *last_entry;
  62. int cnt;
  63. public:
  64. //---------------------------------------------------------------------------------------
  65. // Constructor initializes empty list
  66. //---------------------------------------------------------------------------------------
  67. LList()
  68. {
  69. reset();
  70. }
  71. //---------------------------------------------------------------------------------------
  72. // Reset list to empty state by abandoning contents
  73. //---------------------------------------------------------------------------------------
  74. void reset(void)
  75. {
  76. first_entry = NULL;
  77. last_entry = NULL;
  78. cnt = 0;
  79. }
  80. //---------------------------------------------------------------------------------------
  81. // Return entry count
  82. //---------------------------------------------------------------------------------------
  83. int size(void) const
  84. {
  85. return cnt;
  86. }
  87. //---------------------------------------------------------------------------------------
  88. // Return first list entry (NULL if list empty)
  89. //---------------------------------------------------------------------------------------
  90. T *first(void) const
  91. {
  92. if( first_entry ){
  93. return first_entry->Data;
  94. }
  95. else
  96. {
  97. return NULL;
  98. }
  99. }
  100. //---------------------------------------------------------------------------------------
  101. // Return last list entry (NULL if list empty)
  102. //---------------------------------------------------------------------------------------
  103. T *last(void) const
  104. {
  105. if( last_entry )
  106. {
  107. return last_entry->Data;
  108. }
  109. else
  110. {
  111. return NULL;
  112. }
  113. }
  114. //---------------------------------------------------------------------------------------
  115. // Returns next entry - returns first entry if current == NULL
  116. //---------------------------------------------------------------------------------------
  117. T *next( T* current )
  118. {
  119. if( current == NULL )
  120. {
  121. return first();
  122. }
  123. LListNode<T> *next = findNode( current )->Next;
  124. if( next )
  125. {
  126. return next->Data;
  127. }
  128. else
  129. {
  130. return NULL;
  131. }
  132. }
  133. //---------------------------------------------------------------------------------------
  134. // Returns prev entry - returns last entry if current == NULL
  135. //---------------------------------------------------------------------------------------
  136. T *prev( T *current )
  137. {
  138. if( current == NULL )
  139. {
  140. return last();
  141. }
  142. LListNode<T> *prev = findNode( current )->Prev;
  143. if( prev )
  144. {
  145. return prev->Data;
  146. }
  147. else
  148. {
  149. return NULL;
  150. }
  151. }
  152. //---------------------------------------------------------------------------------------
  153. // Link new item into list before specified entry
  154. // If specified entry==NULL, insert at end of list
  155. //---------------------------------------------------------------------------------------
  156. T *link(T *entry, T *next = NULL)
  157. {
  158. LListNode<T> *prevNode = NULL;
  159. LListNode<T> *nextNode = findNode( next );
  160. LListNode<T> *newNode = new LListNode<T>;
  161. newNode->Data = entry;
  162. if( nextNode == NULL)
  163. {
  164. prevNode = last_entry;
  165. last_entry = newNode;
  166. }
  167. else
  168. {
  169. prevNode = nextNode->Prev;
  170. nextNode->Prev = newNode;
  171. }
  172. if( prevNode == NULL )
  173. {
  174. first_entry = newNode;
  175. }
  176. else
  177. {
  178. prevNode->Next = newNode;
  179. }
  180. newNode->Next = nextNode;
  181. newNode->Prev = prevNode;
  182. ++cnt;
  183. return entry;
  184. }
  185. //---------------------------------------------------------------------------------------
  186. // Link new item into list before specified entry
  187. // If specified entry==NULL, insert at end of list
  188. //---------------------------------------------------------------------------------------
  189. T *link(T &entry, T *next = NULL)
  190. {
  191. T *newEntry = new T;
  192. *newEntry = entry;
  193. return link( newEntry, next );
  194. }
  195. //---------------------------------------------------------------------------------------
  196. // Unlink item from list (without destroying it)
  197. //---------------------------------------------------------------------------------------
  198. void unlink(T *entry)
  199. {
  200. LListNode<T> *entryNode = findNode( entry );
  201. if( !entryNode ) return;
  202. if( entryNode->Prev == NULL )
  203. {
  204. first_entry = entryNode->Next;
  205. }
  206. else
  207. {
  208. entryNode->Prev->Next = entryNode->Next;
  209. }
  210. if( entryNode->Next == NULL )
  211. {
  212. last_entry = entryNode->Prev;
  213. }
  214. else
  215. {
  216. entryNode->Next->Prev = entryNode->Prev;
  217. }
  218. delete entryNode;
  219. --cnt;
  220. }
  221. //---------------------------------------------------------------------------------------
  222. // Allocate entry and insert before specified entry
  223. // If specified entry==NULL, insert at end of list
  224. //---------------------------------------------------------------------------------------
  225. T * alloc( T *next = NULL )
  226. {
  227. T *entry = new T;
  228. if( entry == NULL )
  229. {
  230. return NULL;
  231. }
  232. return link( entry, next );
  233. }
  234. //---------------------------------------------------------------------------------------
  235. // Unlink item from list and destroy it
  236. //---------------------------------------------------------------------------------------
  237. void free(T *entry)
  238. {
  239. unlink(entry);
  240. delete entry;
  241. }
  242. //---------------------------------------------------------------------------------------
  243. // Unlink and destroy all list items
  244. //---------------------------------------------------------------------------------------
  245. void free(void)
  246. {
  247. LListNode<T> *node = NULL;
  248. while( (node = iterate( node ) )!=NULL )
  249. {
  250. LListNode<T> *nodeToKill = node;
  251. node = node->Prev;
  252. free( nodeToKill->Data );
  253. }
  254. }
  255. //---------------------------------------------------------------------------------------
  256. // Find node
  257. //---------------------------------------------------------------------------------------
  258. LListNode<T> *findNode( T *entry )
  259. {
  260. LListNode<T> *it = NULL;
  261. while( (it = iterate( it ) )!=NULL )
  262. {
  263. if( it->Data == entry )
  264. {
  265. return it;
  266. }
  267. }
  268. return NULL;
  269. }
  270. //---------------------------------------------------------------------------------------
  271. // Returns the next node in list
  272. //---------------------------------------------------------------------------------------
  273. LListNode<T> *iterate( LListNode<T> *entry = NULL )
  274. {
  275. if( entry == NULL ) return first_entry;
  276. return entry->Next;
  277. }
  278. };
  279. #endif