LinkedList.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #ifndef CORE_LINKED_LIST_HPP
  2. #define CORE_LINKED_LIST_HPP
  3. #include "utils/ArrayString.hpp"
  4. namespace Core {
  5. template<typename T>
  6. struct LinkedList final {
  7. class Node final {
  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. check_return Error copyFrom(const LinkedList& other) {
  56. LinkedList copy;
  57. for(const T& t : other) {
  58. CORE_RETURN_ERROR(copy.add(t));
  59. }
  60. swap(copy);
  61. return Error::NONE;
  62. }
  63. template<typename... Args>
  64. check_return Error put(Node*& n, Args&&... args) {
  65. n = new Node(Core::forward<Args>(args)...);
  66. if(n == nullptr) {
  67. return Error::OUT_OF_MEMORY;
  68. }
  69. length++;
  70. if(first == nullptr) {
  71. first = n;
  72. last = n;
  73. return Error::NONE;
  74. }
  75. last->next = n;
  76. n->previous = last;
  77. last = n;
  78. return Error::NONE;
  79. }
  80. template<typename... Args>
  81. check_return Error add(Args&&... args) {
  82. Node* n = nullptr;
  83. return put(n, Core::forward<Args>(args)...);
  84. }
  85. Iterator begin() {
  86. return {first};
  87. }
  88. Iterator end() {
  89. return {nullptr};
  90. }
  91. ConstIterator begin() const {
  92. return {first};
  93. }
  94. ConstIterator end() const {
  95. return {nullptr};
  96. }
  97. int getLength() const {
  98. return length;
  99. }
  100. void clear() {
  101. Node* n = first;
  102. while(n != nullptr) {
  103. Node* next = n->next;
  104. delete n;
  105. n = next;
  106. }
  107. length = 0;
  108. first = nullptr;
  109. last = nullptr;
  110. }
  111. template<typename String>
  112. check_return Error toString(String& s) const {
  113. return Core::toString(s, *this);
  114. }
  115. void remove(Node*& n) {
  116. if(n == nullptr) {
  117. return;
  118. }
  119. if(n == first) {
  120. if(first->next != nullptr) {
  121. first->next->previous = nullptr;
  122. }
  123. first = first->next;
  124. }
  125. if(n == last) {
  126. if(last->previous != nullptr) {
  127. last->previous->next = nullptr;
  128. }
  129. last = last->previous;
  130. }
  131. if(n->previous != nullptr) {
  132. n->previous->next = n->next;
  133. }
  134. if(n->next != nullptr) {
  135. n->next->previous = n->previous;
  136. }
  137. length--;
  138. delete n;
  139. n = nullptr;
  140. }
  141. void removeFirst() {
  142. Node* n = first; // prevent first from becoming null
  143. remove(n);
  144. }
  145. void removeLast() {
  146. Node* n = last; // prevent last from becoming null
  147. remove(n);
  148. }
  149. private:
  150. void swap(LinkedList& other) {
  151. Core::swap(first, other.first);
  152. Core::swap(last, other.last);
  153. Core::swap(length, other.length);
  154. }
  155. };
  156. }
  157. #endif