/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #pragma once #include #include #include #include namespace std { template class list { private: NewLock(lock); struct node { T value; node *prev; node *next; node(const T &v, node *p = nullptr, node *n = nullptr) : value(v), prev(p), next(n) {} }; node *head = nullptr; node *tail = nullptr; std::atomic_size_t lSize = 0; public: list() {} ~list() { clear(); } list(const list &other) { *this = other; } void push_back(const T &value) { SmartLock(this->lock); node *nNode = new node(value, tail); if (empty()) head = tail = nNode; else { tail->next = nNode; tail = nNode; } ++lSize; } void pop_back() { SmartLock(this->lock); if (unlikely(empty())) assert(!"list is empty"); else if (head == tail) { delete tail; head = tail = nullptr; --lSize; } else { node *oldTail = tail; tail = tail->prev; tail->next = nullptr; delete oldTail; --lSize; } } void push_front(const T &value) { SmartLock(this->lock); node *nNode = new node(value, nullptr, head); if (empty()) head = tail = nNode; else { head->prev = nNode; head = nNode; } ++lSize; } void pop_front() { if (unlikely(empty())) { assert(!"list is empty"); } if (head == tail) { SmartLock(this->lock); delete head; head = tail = nullptr; --lSize; } else { SmartLock(this->lock); node *old_head = head; head = head->next; head->prev = nullptr; delete old_head; --lSize; } } template void emplace_back(Args &&...args) { assert(sizeof...(args) > 0); SmartLock(this->lock); node *nNode = new node(T(std::forward(args)...), tail); if (this->empty()) head = tail = nNode; else { tail->next = nNode; tail = nNode; } ++lSize; } template void emplace_front(Args &&...args) { assert(sizeof...(args) > 0); SmartLock(this->lock); node *nNode = new node(T(std::forward(args)...), nullptr, head); if (this->empty()) head = tail = nNode; else { head->prev = nNode; head = nNode; } ++lSize; } T &front() { SmartLock(this->lock); return head->value; } const T &front() const { SmartLock(this->lock); return head->value; } T &back() { SmartLock(this->lock); return tail->value; } const T &back() const { SmartLock(this->lock); return tail->value; } bool empty() const { return lSize.load() == 0; } size_t size() const { return lSize; } void clear() { while (!empty()) pop_back(); } void merge(list &other) { if (this == &other) return; while (other.empty() == false) { T &fr = other.front(); push_back(fr); other.pop_front(); } } size_t remove(const T &value) { SmartLock(this->lock); node *p = head; size_t count = 0; while (p != nullptr) { if (p->value == value) { if (p->prev) p->prev->next = p->next; if (p->next) p->next->prev = p->prev; if (p == head) head = p->next; if (p == tail) tail = p->prev; delete p; --lSize; ++count; } p = p->next; } return count; } template size_t remove_if(UnaryPredicate p) { SmartLock(this->lock); node *n = head; size_t count = 0; while (n != nullptr) { if (p(n->value)) { if (n->prev) n->prev->next = n->next; if (n->next) n->next->prev = n->prev; if (n == head) head = n->next; if (n == tail) tail = n->prev; delete n; --lSize; ++count; } n = n->next; } return count; } void reverse() { if (empty()) return; SmartLock(this->lock); node *p = head; while (p != nullptr) { node *tmp = p->next; p->next = p->prev; p->prev = tmp; p = tmp; } node *tmp = head; head = tail; tail = tmp; } void sort() { if (empty()) return; SmartLock(this->lock); bool swapped = true; while (swapped) { swapped = false; node *p = head; while (p->next != nullptr) { if (p->value > p->next->value) { T tmp = p->value; p->value = p->next->value; p->next->value = tmp; swapped = true; } p = p->next; } } } template void sort(Compare comp) { if (empty()) return; SmartLock(this->lock); bool swapped = true; while (swapped) { swapped = false; node *p = head; while (p->next != nullptr) { if (comp(p->value, p->next->value)) { T tmp = p->value; p->value = p->next->value; p->next->value = tmp; swapped = true; } p = p->next; } } } /* Non-STL function */ T &operator[](size_t Index) { SmartLock(this->lock); node *p = head; for (size_t i = 0; i < Index; ++i) p = p->next; return p->value; } list &operator=(const list &other) { if (this == &other) return *this; for (const T &value : other) push_back(value); return *this; } class iterator { private: node *_node; friend class list; public: iterator(node *p = nullptr) : _node(p) {} T &operator*() const { return _node->value; } T *operator->() const { return &_node->value; } iterator &operator++() { _node = _node->next; return *this; } iterator &operator--() { _node = _node->prev; return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } iterator operator--(int) { iterator tmp = *this; --*this; return tmp; } bool operator==(const iterator &rhs) const { return _node == rhs._node; } bool operator!=(const iterator &rhs) const { return _node != rhs._node; } }; iterator begin() { return iterator(head); } iterator end() { return iterator(nullptr); } const iterator begin() const { return iterator(head); } const iterator end() const { return iterator(nullptr); } iterator insert(iterator pos, const T &value) { if (pos == end()) { push_back(value); return iterator(tail); } else if (pos == begin()) { push_front(value); return iterator(head); } else { SmartLock(this->lock); node *p = pos.node; node *nNode = new node(value, p->prev, p); p->prev->next = nNode; p->prev = nNode; ++lSize; return iterator(nNode); } } iterator erase(iterator pos) { if (pos == end()) return end(); else if (pos == begin()) { pop_front(); return begin(); } else { SmartLock(this->lock); node *p = pos._node; if (p->prev) p->prev->next = p->next; if (p->next) p->next->prev = p->prev; if (head == p) head = p->next; if (tail == p) tail = p->prev; iterator ret(p->next); delete p; --lSize; return ret; } } }; }