/*
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
namespace std
{
template
class list
{
private:
struct lNode
{
T value;
lNode *prev;
lNode *next;
lNode(const T &v, lNode *p = nullptr, lNode *n = nullptr)
: value(v), prev(p), next(n) {}
};
lNode *head;
lNode *tail;
size_t size;
public:
list() : head(nullptr), tail(nullptr), size(0) {}
~list() { clear(); }
list(const list &other) : head(nullptr), tail(nullptr), size(0) { *this = other; }
void push_back(const T &value)
{
lNode *new_node = new lNode(value, tail, nullptr);
if (empty())
{
head = tail = new_node;
}
else
{
tail->next = new_node;
tail = new_node;
}
++size;
}
void pop_back()
{
if (unlikely(empty()))
{
assert(!"list is empty");
}
else if (head == tail)
{
delete tail;
head = tail = nullptr;
--size;
}
else
{
lNode *old_tail = tail;
tail = tail->prev;
tail->next = nullptr;
delete old_tail;
--size;
}
}
void push_front(const T &value)
{
lNode *new_node = new lNode(value, nullptr, head);
if (empty())
{
head = tail = new_node;
}
else
{
head->prev = new_node;
head = new_node;
}
++size;
}
void pop_front()
{
if (unlikely(empty()))
{
assert(!"list is empty");
}
if (head == tail)
{
delete head;
head = tail = nullptr;
--size;
}
else
{
lNode *old_head = head;
head = head->next;
head->prev = nullptr;
delete old_head;
--size;
}
}
bool empty() const { return size == 0; }
void clear()
{
while (!empty())
pop_back();
}
list &operator=(const list &other)
{
if (this != &other)
{
clear();
for (const T &value : other)
{
push_back(value);
}
}
return *this;
}
class iterator
{
private:
lNode *node;
friend class list;
public:
iterator(lNode *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); }
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
{
lNode *p = pos.node;
lNode *new_node = new lNode(value, p->prev, p);
p->prev->next = new_node;
p->prev = new_node;
++size;
return iterator(new_node);
}
}
iterator erase(iterator pos)
{
lNode *p = pos.node;
iterator next(p->next);
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
--size;
return next;
}
};
}