summaryrefslogtreecommitdiff
path: root/euler/include/std/list.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'euler/include/std/list.hpp')
-rw-r--r--euler/include/std/list.hpp157
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;
+ }
+
+ };
+
+}