LinkedList.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. size_t length;
  41. public:
  42. LinkedList() : first(nullptr), last(nullptr), length(0) {
  43. }
  44. LinkedList(const LinkedList& other) : LinkedList() {
  45. for(const T& t : other) {
  46. add(t);
  47. }
  48. }
  49. LinkedList(LinkedList&& other) : LinkedList() {
  50. swap(other);
  51. }
  52. ~LinkedList() {
  53. clear();
  54. }
  55. LinkedList& operator=(LinkedList other) {
  56. swap(other);
  57. return *this;
  58. }
  59. template<typename... Args>
  60. Node* put(Args&&... args) {
  61. Node* n = new(noThrow) Node(Core::forward<Args>(args)...);
  62. length++;
  63. if(first == nullptr) {
  64. first = n;
  65. last = n;
  66. return n;
  67. }
  68. last->next = n;
  69. n->previous = last;
  70. last = n;
  71. return n;
  72. }
  73. template<typename... Args>
  74. LinkedList& add(Args&&... args) {
  75. put(Core::forward<Args>(args)...);
  76. return *this;
  77. }
  78. Iterator begin() {
  79. return {first};
  80. }
  81. Iterator end() {
  82. return {nullptr};
  83. }
  84. ConstIterator begin() const {
  85. return {first};
  86. }
  87. ConstIterator end() const {
  88. return {nullptr};
  89. }
  90. size_t getLength() const {
  91. return length;
  92. }
  93. void clear() {
  94. Node* n = first;
  95. while(n != nullptr) {
  96. Node* next = n->next;
  97. delete n;
  98. n = next;
  99. }
  100. length = 0;
  101. first = nullptr;
  102. last = nullptr;
  103. }
  104. template<typename String>
  105. check_return Error toString(String& s) const {
  106. return Core::toString(s, *this);
  107. }
  108. void remove(Node*& n) {
  109. if(n == nullptr) {
  110. return;
  111. }
  112. if(n == first) {
  113. if(first->next != nullptr) {
  114. first->next->previous = nullptr;
  115. }
  116. first = first->next;
  117. }
  118. if(n == last) {
  119. if(last->previous != nullptr) {
  120. last->previous->next = nullptr;
  121. }
  122. last = last->previous;
  123. }
  124. if(n->previous != nullptr) {
  125. n->previous->next = n->next;
  126. }
  127. if(n->next != nullptr) {
  128. n->next->previous = n->previous;
  129. }
  130. length--;
  131. delete n;
  132. n = nullptr;
  133. }
  134. void removeFirst() {
  135. Node* n = first; // prevent first from becoming null
  136. remove(n);
  137. }
  138. void removeLast() {
  139. Node* n = last; // prevent last from becoming null
  140. remove(n);
  141. }
  142. void swap(LinkedList& other) {
  143. Core::swap(first, other.first);
  144. Core::swap(last, other.last);
  145. Core::swap(length, other.length);
  146. }
  147. };
  148. }
  149. #endif