LinkedList.hpp 4.6 KB

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