irrList.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #ifndef __IRR_LIST_H_INCLUDED__
  5. #define __IRR_LIST_H_INCLUDED__
  6. #include "irrTypes.h"
  7. #include "irrAllocator.h"
  8. #include "irrMath.h"
  9. namespace irr
  10. {
  11. namespace core
  12. {
  13. //! Doubly linked list template.
  14. template <class T>
  15. class list
  16. {
  17. private:
  18. //! List element node with pointer to previous and next element in the list.
  19. struct SKListNode
  20. {
  21. SKListNode(const T& e) : Next(0), Prev(0), Element(e) {}
  22. SKListNode* Next;
  23. SKListNode* Prev;
  24. T Element;
  25. };
  26. public:
  27. class ConstIterator;
  28. //! List iterator.
  29. class Iterator
  30. {
  31. public:
  32. Iterator() : Current(0) {}
  33. Iterator& operator ++() { Current = Current->Next; return *this; }
  34. Iterator& operator --() { Current = Current->Prev; return *this; }
  35. Iterator operator ++(s32) { Iterator tmp = *this; Current = Current->Next; return tmp; }
  36. Iterator operator --(s32) { Iterator tmp = *this; Current = Current->Prev; return tmp; }
  37. Iterator& operator +=(s32 num)
  38. {
  39. if(num > 0)
  40. {
  41. while (num-- && this->Current != 0) ++(*this);
  42. }
  43. else
  44. {
  45. while(num++ && this->Current != 0) --(*this);
  46. }
  47. return *this;
  48. }
  49. Iterator operator + (s32 num) const { Iterator tmp = *this; return tmp += num; }
  50. Iterator& operator -=(s32 num) { return (*this)+=(-num); }
  51. Iterator operator - (s32 num) const { return (*this)+ (-num); }
  52. bool operator ==(const Iterator& other) const { return Current == other.Current; }
  53. bool operator !=(const Iterator& other) const { return Current != other.Current; }
  54. bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
  55. bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
  56. T & operator * () { return Current->Element; }
  57. T * operator ->() { return &Current->Element; }
  58. private:
  59. explicit Iterator(SKListNode* begin) : Current(begin) {}
  60. SKListNode* Current;
  61. friend class list<T>;
  62. friend class ConstIterator;
  63. };
  64. //! List iterator for const access.
  65. class ConstIterator
  66. {
  67. public:
  68. ConstIterator() : Current(0) {}
  69. ConstIterator(const Iterator& iter) : Current(iter.Current) {}
  70. ConstIterator& operator ++() { Current = Current->Next; return *this; }
  71. ConstIterator& operator --() { Current = Current->Prev; return *this; }
  72. ConstIterator operator ++(s32) { ConstIterator tmp = *this; Current = Current->Next; return tmp; }
  73. ConstIterator operator --(s32) { ConstIterator tmp = *this; Current = Current->Prev; return tmp; }
  74. ConstIterator& operator +=(s32 num)
  75. {
  76. if(num > 0)
  77. {
  78. while(num-- && this->Current != 0) ++(*this);
  79. }
  80. else
  81. {
  82. while(num++ && this->Current != 0) --(*this);
  83. }
  84. return *this;
  85. }
  86. ConstIterator operator + (s32 num) const { ConstIterator tmp = *this; return tmp += num; }
  87. ConstIterator& operator -=(s32 num) { return (*this)+=(-num); }
  88. ConstIterator operator - (s32 num) const { return (*this)+ (-num); }
  89. bool operator ==(const ConstIterator& other) const { return Current == other.Current; }
  90. bool operator !=(const ConstIterator& other) const { return Current != other.Current; }
  91. bool operator ==(const Iterator& other) const { return Current == other.Current; }
  92. bool operator !=(const Iterator& other) const { return Current != other.Current; }
  93. const T & operator * () { return Current->Element; }
  94. const T * operator ->() { return &Current->Element; }
  95. ConstIterator & operator =(const Iterator & iterator) { Current = iterator.Current; return *this; }
  96. private:
  97. explicit ConstIterator(SKListNode* begin) : Current(begin) {}
  98. SKListNode* Current;
  99. friend class Iterator;
  100. friend class list<T>;
  101. };
  102. //! Default constructor for empty list.
  103. list()
  104. : First(0), Last(0), Size(0) {}
  105. //! Copy constructor.
  106. list(const list<T>& other) : First(0), Last(0), Size(0)
  107. {
  108. *this = other;
  109. }
  110. //! Destructor
  111. ~list()
  112. {
  113. clear();
  114. }
  115. //! Assignment operator
  116. void operator=(const list<T>& other)
  117. {
  118. if(&other == this)
  119. {
  120. return;
  121. }
  122. clear();
  123. SKListNode* node = other.First;
  124. while(node)
  125. {
  126. push_back(node->Element);
  127. node = node->Next;
  128. }
  129. }
  130. //! Returns amount of elements in list.
  131. /** \return Amount of elements in the list. */
  132. u32 size() const
  133. {
  134. return Size;
  135. }
  136. u32 getSize() const
  137. {
  138. return Size;
  139. }
  140. //! Clears the list, deletes all elements in the list.
  141. /** All existing iterators of this list will be invalid. */
  142. void clear()
  143. {
  144. while(First)
  145. {
  146. SKListNode * next = First->Next;
  147. allocator.destruct(First);
  148. allocator.deallocate(First);
  149. First = next;
  150. }
  151. //First = 0; handled by loop
  152. Last = 0;
  153. Size = 0;
  154. }
  155. //! Checks for empty list.
  156. /** \return True if the list is empty and false if not. */
  157. bool empty() const
  158. {
  159. return (First == 0);
  160. }
  161. //! Adds an element at the end of the list.
  162. /** \param element Element to add to the list. */
  163. void push_back(const T& element)
  164. {
  165. SKListNode* node = allocator.allocate(1);
  166. allocator.construct(node, element);
  167. ++Size;
  168. if (First == 0)
  169. First = node;
  170. node->Prev = Last;
  171. if (Last != 0)
  172. Last->Next = node;
  173. Last = node;
  174. }
  175. //! Adds an element at the begin of the list.
  176. /** \param element: Element to add to the list. */
  177. void push_front(const T& element)
  178. {
  179. SKListNode* node = allocator.allocate(1);
  180. allocator.construct(node, element);
  181. ++Size;
  182. if (First == 0)
  183. {
  184. Last = node;
  185. First = node;
  186. }
  187. else
  188. {
  189. node->Next = First;
  190. First->Prev = node;
  191. First = node;
  192. }
  193. }
  194. //! Gets first node.
  195. /** \return A list iterator pointing to the beginning of the list. */
  196. Iterator begin()
  197. {
  198. return Iterator(First);
  199. }
  200. //! Gets first node.
  201. /** \return A const list iterator pointing to the beginning of the list. */
  202. ConstIterator begin() const
  203. {
  204. return ConstIterator(First);
  205. }
  206. //! Gets end node.
  207. /** \return List iterator pointing to null. */
  208. Iterator end()
  209. {
  210. return Iterator(0);
  211. }
  212. //! Gets end node.
  213. /** \return Const list iterator pointing to null. */
  214. ConstIterator end() const
  215. {
  216. return ConstIterator(0);
  217. }
  218. //! Gets last element.
  219. /** \return List iterator pointing to the last element of the list. */
  220. Iterator getLast()
  221. {
  222. return Iterator(Last);
  223. }
  224. //! Gets last element.
  225. /** \return Const list iterator pointing to the last element of the list. */
  226. ConstIterator getLast() const
  227. {
  228. return ConstIterator(Last);
  229. }
  230. //! Inserts an element after an element.
  231. /** \param it Iterator pointing to element after which the new element
  232. should be inserted.
  233. \param element The new element to be inserted into the list.
  234. */
  235. void insert_after(const Iterator& it, const T& element)
  236. {
  237. SKListNode* node = allocator.allocate(1);
  238. allocator.construct(node, element);
  239. node->Next = it.Current->Next;
  240. if (it.Current->Next)
  241. it.Current->Next->Prev = node;
  242. node->Prev = it.Current;
  243. it.Current->Next = node;
  244. ++Size;
  245. if (it.Current == Last)
  246. Last = node;
  247. }
  248. //! Inserts an element before an element.
  249. /** \param it Iterator pointing to element before which the new element
  250. should be inserted.
  251. \param element The new element to be inserted into the list.
  252. */
  253. void insert_before(const Iterator& it, const T& element)
  254. {
  255. SKListNode* node = allocator.allocate(1);
  256. allocator.construct(node, element);
  257. node->Prev = it.Current->Prev;
  258. if (it.Current->Prev)
  259. it.Current->Prev->Next = node;
  260. node->Next = it.Current;
  261. it.Current->Prev = node;
  262. ++Size;
  263. if (it.Current == First)
  264. First = node;
  265. }
  266. //! Erases an element.
  267. /** \param it Iterator pointing to the element which shall be erased.
  268. \return Iterator pointing to next element. */
  269. Iterator erase(Iterator& it)
  270. {
  271. // suggest changing this to a const Iterator& and
  272. // working around line: it.Current = 0 (possibly with a mutable, or just let it be garbage?)
  273. Iterator returnIterator(it);
  274. ++returnIterator;
  275. if(it.Current == First)
  276. {
  277. First = it.Current->Next;
  278. }
  279. else
  280. {
  281. it.Current->Prev->Next = it.Current->Next;
  282. }
  283. if(it.Current == Last)
  284. {
  285. Last = it.Current->Prev;
  286. }
  287. else
  288. {
  289. it.Current->Next->Prev = it.Current->Prev;
  290. }
  291. allocator.destruct(it.Current);
  292. allocator.deallocate(it.Current);
  293. it.Current = 0;
  294. --Size;
  295. return returnIterator;
  296. }
  297. //! Swap the content of this list container with the content of another list
  298. /** Afterward this object will contain the content of the other object and the other
  299. object will contain the content of this object. Iterators will afterward be valid for
  300. the swapped object.
  301. \param other Swap content with this object */
  302. void swap(list<T>& other)
  303. {
  304. core::swap(First, other.First);
  305. core::swap(Last, other.Last);
  306. core::swap(Size, other.Size);
  307. core::swap(allocator, other.allocator); // memory is still released by the same allocator used for allocation
  308. }
  309. typedef T value_type;
  310. typedef u32 size_type;
  311. private:
  312. SKListNode* First;
  313. SKListNode* Last;
  314. u32 Size;
  315. irrAllocator<SKListNode> allocator;
  316. };
  317. } // end namespace core
  318. }// end namespace irr
  319. #endif