mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-10 23:09:18 +00:00
Update std headers
This commit is contained in:
221
include_std/list
Normal file
221
include_std/list
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T>
|
||||
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 (empty())
|
||||
{
|
||||
throw std::runtime_error("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 (empty())
|
||||
{
|
||||
throw std::runtime_error("list is empty");
|
||||
}
|
||||
else 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;
|
||||
}
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user