LinkedList.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #ifndef CORE_LINKED_LIST_H
  2. #define CORE_LINKED_LIST_H
  3. #include "utils/ArrayString.h"
  4. namespace Core {
  5. template<typename T>
  6. struct LinkedList final {
  7. class Node {
  8. friend LinkedList;
  9. Node* next;
  10. Node* previous;
  11. public:
  12. T data;
  13. template<typename... Args>
  14. Node(Args&&... args)
  15. : next(nullptr), previous(nullptr),
  16. data(Core::forward<Args>(args)...) {
  17. }
  18. };
  19. template<typename NT, typename R>
  20. struct IteratorBase final {
  21. NT* current;
  22. public:
  23. IteratorBase& operator++() {
  24. current = current->next;
  25. return *this;
  26. }
  27. bool operator!=(const IteratorBase& other) const {
  28. return current != other.current;
  29. }
  30. R& operator*() const {
  31. return current->data;
  32. }
  33. };
  34. using Iterator = IteratorBase<Node, T>;
  35. using ConstIterator = IteratorBase<const Node, const T>;
  36. private:
  37. Node* first;
  38. Node* last;
  39. int length;
  40. public:
  41. LinkedList() : first(nullptr), last(nullptr), length(0) {
  42. }
  43. LinkedList(const LinkedList& other) = delete;
  44. LinkedList(LinkedList&& other) : LinkedList() {
  45. swap(other);
  46. }
  47. ~LinkedList() {
  48. clear();
  49. }
  50. LinkedList& operator=(const LinkedList& other) = delete;
  51. LinkedList& operator=(LinkedList&& other) {
  52. swap(other);
  53. return *this;
  54. }
  55. // returns true on error
  56. check_return bool copyFrom(const LinkedList& other) {
  57. LinkedList copy;
  58. for(const T& t : other) {
  59. if(copy.add(t) == nullptr) {
  60. return true;
  61. }
  62. }
  63. swap(copy);
  64. return false;
  65. }
  66. // returns a nullptr on error
  67. template<typename... Args>
  68. check_return Node* add(Args&&... args) {
  69. Node* n = new Node(Core::forward<Args>(args)...);
  70. if(n == nullptr) {
  71. return nullptr;
  72. }
  73. length++;
  74. if(first == nullptr) {
  75. first = n;
  76. last = n;
  77. return n;
  78. }
  79. last->next = n;
  80. n->previous = last;
  81. last = n;
  82. return n;
  83. }
  84. Iterator begin() {
  85. return {first};
  86. }
  87. Iterator end() {
  88. return {nullptr};
  89. }
  90. ConstIterator begin() const {
  91. return {first};
  92. }
  93. ConstIterator end() const {
  94. return {nullptr};
  95. }
  96. int getLength() const {
  97. return length;
  98. }
  99. void clear() {
  100. Node* n = first;
  101. while(n != nullptr) {
  102. Node* next = n->next;
  103. delete n;
  104. n = next;
  105. }
  106. length = 0;
  107. first = nullptr;
  108. last = nullptr;
  109. }
  110. // returns true on error
  111. template<int L>
  112. check_return bool toString(ArrayString<L>& s) const {
  113. if(s.append("[")) {
  114. return true;
  115. }
  116. auto iter = begin();
  117. for(int i = 0; i < length - 1; i++) {
  118. if(s.append(*iter) || s.append(", ")) {
  119. return true;
  120. }
  121. ++iter;
  122. }
  123. if(length > 0 && s.append(*iter)) {
  124. return true;
  125. }
  126. return s.append("]");
  127. }
  128. void remove(Node*& n) {
  129. if(n == nullptr) {
  130. return;
  131. }
  132. if(n == first) {
  133. if(first->next != nullptr) {
  134. first->next->previous = nullptr;
  135. }
  136. first = first->next;
  137. }
  138. if(n == last) {
  139. if(last->previous != nullptr) {
  140. last->previous->next = nullptr;
  141. }
  142. last = last->previous;
  143. }
  144. if(n->previous != nullptr) {
  145. n->previous->next = n->next;
  146. }
  147. if(n->next != nullptr) {
  148. n->next->previous = n->previous;
  149. }
  150. length--;
  151. delete n;
  152. n = nullptr;
  153. }
  154. void removeFirst() {
  155. Node* n = first; // prevent first from becoming null
  156. remove(n);
  157. }
  158. void removeLast() {
  159. Node* n = last; // prevent last from becoming null
  160. remove(n);
  161. }
  162. private:
  163. void swap(LinkedList& other) {
  164. Core::swap(first, other.first);
  165. Core::swap(last, other.last);
  166. Core::swap(length, other.length);
  167. }
  168. };
  169. }
  170. #endif