diff options
author | Benji Dial <benji@benjidial.net> | 2024-07-29 11:27:22 -0400 |
---|---|---|
committer | Benji Dial <benji@benjidial.net> | 2024-07-29 11:27:22 -0400 |
commit | be691582ee12613278af24cb5a824eeb357f6324 (patch) | |
tree | 5982ca3aad5257f515c93f62735ff3d630aa3ab3 /euler/include/std/list.hpp | |
parent | 3636fd21e079c47bd8d62e773e178f68fe9c2052 (diff) | |
download | hilbert-os-be691582ee12613278af24cb5a824eeb357f6324.tar.gz |
some work on compositor
Diffstat (limited to 'euler/include/std/list.hpp')
-rw-r--r-- | euler/include/std/list.hpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/euler/include/std/list.hpp b/euler/include/std/list.hpp new file mode 100644 index 0000000..77eaaec --- /dev/null +++ b/euler/include/std/list.hpp @@ -0,0 +1,157 @@ +#pragma once + +#include <memory> + +namespace std { + + template <class T, class Allocator = std::allocator<T>> + class list { + + public: + struct node { + T value; + node *prev; + node *next; + }; + + template <class V> + struct generic_iterator { + + node *the_node; + + bool operator ==(const generic_iterator &other) { + return the_node == other.the_node; + } + + bool operator !=(const generic_iterator &other) { + return the_node != other.the_node; + } + + V &operator *() { + return the_node->value; + } + + V *operator ->() { + return &the_node->value; + } + + generic_iterator &operator ++() { + the_node = the_node->next; + return *this; + } + + }; + + using iterator = generic_iterator<T>; + using const_iterator = generic_iterator<const T>; + + private: + node *first_node; + node *last_node; + size_t count; + + public: + void push_back(const T &value) { + node *n = new node { .value = value, + .prev = last_node, .next = 0 }; + if (last_node) last_node->next = n; + else first_node = n; + last_node = n; + ++count; + } + + void push_back(T &&value) { + node *n = new node { + .value = std::move(value), + .prev = last_node, .next = 0 }; + if (last_node) last_node->next = n; + else first_node = n; + last_node = n; + ++count; + } + + iterator erase(iterator pos) { + --count; + auto *n = pos.the_node; + auto *r = n->next; + if (n->prev) n->prev->next = n->next; + else first_node = n->next; + if (n->next) n->next->prev = n->prev; + else last_node = n->prev; + delete n; + return iterator { .the_node = r }; + } + + iterator begin() const noexcept { + return iterator { .the_node = first_node }; + } + + iterator end() const noexcept { + return iterator { .the_node = 0 }; + } + + size_t remove(const T &value) { + size_t removed = 0; + auto it = begin(); + while (it != end()) + if (*it == value) { + it = erase(it); + ++removed; + } + else + ++it; + count -= removed; + return removed; + } + + list() : first_node(0), last_node(0), count(0) {} + + list(const list &other) : first_node(0), last_node(0), count(0) { + for (node *n = other.first_node; n; n = n->next) + push_back(n->value); + } + + list(list &&other) : first_node(other.first_node), + last_node(other.last_node), count(other.count) { + other.first_node = 0; + other.last_node = 0; + other.count = 0; + } + + void clear() { + + if (count == 0) return; + + for (node *n = first_node->next; n; n = n->next) + delete n->prev; + delete last_node; + + first_node = 0; + last_node = 0; + count = 0; + + } + + ~list() { + clear(); + } + + list &operator =(const list &other) { + clear(); + for (node *n = other.first_node; n; n = n->next) + push_back(n->value); + } + + list &operator =(list &&other) { + clear(); + first_node = other.first_node; + last_node = other.last_node; + count = other.count; + other.first_node = 0; + other.last_node = 0; + other.count = 0; + } + + }; + +} |