123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #ifndef CORE_LINKED_LIST_HPP
- #define CORE_LINKED_LIST_HPP
- #include "utils/ArrayString.hpp"
- namespace Core {
- template<typename T>
- struct LinkedList final {
- class Node final {
- friend LinkedList;
- Node* next;
- Node* previous;
- public:
- T data;
- template<typename... Args>
- Node(Args&&... args)
- : next(nullptr), previous(nullptr),
- data(Core::forward<Args>(args)...) {
- }
- };
- template<typename NT, typename R>
- struct IteratorBase final {
- NT* current;
- public:
- IteratorBase& operator++() {
- current = current->next;
- return *this;
- }
- bool operator!=(const IteratorBase& other) const {
- return current != other.current;
- }
- R& operator*() const {
- return current->data;
- }
- };
- using Iterator = IteratorBase<Node, T>;
- using ConstIterator = IteratorBase<const Node, const T>;
- private:
- Node* first;
- Node* last;
- int length;
- public:
- LinkedList() : first(nullptr), last(nullptr), length(0) {
- }
- LinkedList(const LinkedList& other) = delete;
- LinkedList(LinkedList&& other) : LinkedList() {
- swap(other);
- }
- ~LinkedList() {
- clear();
- }
- LinkedList& operator=(const LinkedList& other) = delete;
- LinkedList& operator=(LinkedList&& other) {
- swap(other);
- return *this;
- }
- check_return Error copyFrom(const LinkedList& other) {
- LinkedList copy;
- for(const T& t : other) {
- CORE_RETURN_ERROR(copy.add(t));
- }
- swap(copy);
- return Error::NONE;
- }
- template<typename... Args>
- check_return Error put(Node*& n, Args&&... args) {
- n = new Node(Core::forward<Args>(args)...);
- if(n == nullptr) {
- return Error::OUT_OF_MEMORY;
- }
- length++;
- if(first == nullptr) {
- first = n;
- last = n;
- return Error::NONE;
- }
- last->next = n;
- n->previous = last;
- last = n;
- return Error::NONE;
- }
- template<typename... Args>
- check_return Error add(Args&&... args) {
- Node* n = nullptr;
- return put(n, Core::forward<Args>(args)...);
- }
- Iterator begin() {
- return {first};
- }
- Iterator end() {
- return {nullptr};
- }
- ConstIterator begin() const {
- return {first};
- }
- ConstIterator end() const {
- return {nullptr};
- }
- int getLength() const {
- return length;
- }
- void clear() {
- Node* n = first;
- while(n != nullptr) {
- Node* next = n->next;
- delete n;
- n = next;
- }
- length = 0;
- first = nullptr;
- last = nullptr;
- }
- template<typename String>
- check_return Error toString(String& s) const {
- return Core::toString(s, *this);
- }
- void remove(Node*& n) {
- if(n == nullptr) {
- return;
- }
- if(n == first) {
- if(first->next != nullptr) {
- first->next->previous = nullptr;
- }
- first = first->next;
- }
- if(n == last) {
- if(last->previous != nullptr) {
- last->previous->next = nullptr;
- }
- last = last->previous;
- }
- if(n->previous != nullptr) {
- n->previous->next = n->next;
- }
- if(n->next != nullptr) {
- n->next->previous = n->previous;
- }
- length--;
- delete n;
- n = nullptr;
- }
- void removeFirst() {
- Node* n = first; // prevent first from becoming null
- remove(n);
- }
- void removeLast() {
- Node* n = last; // prevent last from becoming null
- remove(n);
- }
- private:
- void swap(LinkedList& other) {
- Core::swap(first, other.first);
- Core::swap(last, other.last);
- Core::swap(length, other.length);
- }
- };
- }
- #endif
|