2022-10-09 05:13:17 +00:00
|
|
|
#ifndef _RSTL_LIST
|
|
|
|
#define _RSTL_LIST
|
2022-04-10 00:17:06 +00:00
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
|
2022-10-19 03:35:06 +00:00
|
|
|
#include "rstl/construct.hpp"
|
2022-08-09 23:03:51 +00:00
|
|
|
#include "rstl/rmemory_allocator.hpp"
|
2022-04-10 00:17:06 +00:00
|
|
|
|
|
|
|
namespace rstl {
|
|
|
|
template < typename T, typename Alloc = rmemory_allocator >
|
|
|
|
class list {
|
|
|
|
public:
|
2022-10-16 16:27:17 +00:00
|
|
|
class iterator;
|
|
|
|
class const_iterator;
|
2022-10-19 03:35:06 +00:00
|
|
|
iterator erase(const iterator& item);
|
|
|
|
|
2022-10-16 16:27:17 +00:00
|
|
|
private:
|
2022-12-01 16:19:53 +00:00
|
|
|
struct node;
|
|
|
|
node* erase(node* item);
|
2022-10-16 16:27:17 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
list()
|
2022-10-19 03:35:06 +00:00
|
|
|
: x4_start(reinterpret_cast< node* >(&xc_empty_prev))
|
|
|
|
, x8_end(reinterpret_cast< node* >(&xc_empty_prev))
|
2022-10-19 03:37:39 +00:00
|
|
|
, xc_empty_prev(reinterpret_cast< node* >(&xc_empty_prev))
|
|
|
|
, x10_empty_next(reinterpret_cast< node* >(&xc_empty_prev))
|
2022-10-19 03:35:06 +00:00
|
|
|
, x14_count(0) {}
|
2022-11-15 13:45:15 +00:00
|
|
|
~list();
|
2022-11-27 00:26:12 +00:00
|
|
|
|
2022-10-19 03:35:06 +00:00
|
|
|
void push_back(const T& val) { do_insert_before(x8_end, val); }
|
2022-11-27 00:26:12 +00:00
|
|
|
void clear() { erase(begin(), end()); }
|
2022-10-16 16:27:17 +00:00
|
|
|
|
2022-11-10 06:50:18 +00:00
|
|
|
size_t size() const { return x14_count; }
|
|
|
|
bool empty() const { return x14_count == 0; }
|
|
|
|
|
2022-12-01 16:19:53 +00:00
|
|
|
void pop_front() {
|
|
|
|
erase(x4_start);
|
|
|
|
}
|
|
|
|
|
2022-10-16 16:27:17 +00:00
|
|
|
iterator begin() { return iterator(x4_start); }
|
|
|
|
const_iterator begin() const { return const_iterator(x4_start); }
|
|
|
|
iterator end() { return iterator(x8_end); }
|
|
|
|
const_iterator end() const { return const_iterator(x8_end); }
|
2022-04-10 00:17:06 +00:00
|
|
|
|
2022-11-10 06:50:18 +00:00
|
|
|
iterator erase(const iterator& start, const iterator& end) {
|
2022-12-01 16:19:53 +00:00
|
|
|
node* last = end.get_node();
|
|
|
|
node* it = start.get_node();
|
|
|
|
while (it != last) {
|
|
|
|
it = erase(it);
|
2022-10-20 14:10:03 +00:00
|
|
|
}
|
2022-12-01 16:19:53 +00:00
|
|
|
return iterator(it);
|
2022-10-20 14:10:03 +00:00
|
|
|
}
|
|
|
|
|
2022-04-10 00:17:06 +00:00
|
|
|
private:
|
|
|
|
struct node {
|
|
|
|
node* x0_prev;
|
|
|
|
node* x4_next;
|
2022-10-19 03:35:06 +00:00
|
|
|
uchar x8_item[sizeof(T)];
|
2022-09-13 04:26:54 +00:00
|
|
|
|
2022-10-19 03:35:06 +00:00
|
|
|
node(node* prev, node* next) : x0_prev(prev), x4_next(next) {}
|
2022-11-27 00:26:12 +00:00
|
|
|
~node() { get_value()->~T(); }
|
2022-10-01 06:19:09 +00:00
|
|
|
|
|
|
|
node* get_prev() const { return x0_prev; }
|
|
|
|
node* get_next() const { return x4_next; }
|
2022-10-19 03:35:06 +00:00
|
|
|
void set_prev(node* prev) { x0_prev = prev; }
|
|
|
|
void set_next(node* next) { x4_next = next; }
|
|
|
|
T* get_value() { return reinterpret_cast< T* >(&x8_item); }
|
2022-10-20 16:32:57 +00:00
|
|
|
const T* get_value() const { return reinterpret_cast< const T* >(&x8_item); }
|
2022-04-10 00:17:06 +00:00
|
|
|
};
|
|
|
|
|
2022-10-19 03:35:06 +00:00
|
|
|
node* create_node(node* prev, node* next, const T& val) {
|
2023-02-04 09:18:12 +00:00
|
|
|
node* n;
|
|
|
|
x0_allocator.allocate(n, 1);
|
|
|
|
new(n) node(prev, next);
|
2022-10-19 03:35:06 +00:00
|
|
|
construct(n->get_value(), val);
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
void do_insert_before(node* n, const T& val) {
|
|
|
|
node* nn = create_node(n->get_prev(), n, val);
|
|
|
|
if (n == x4_start) {
|
|
|
|
x4_start = nn;
|
|
|
|
}
|
|
|
|
nn->get_prev()->set_next(nn);
|
|
|
|
nn->get_next()->set_prev(nn);
|
|
|
|
++x14_count;
|
|
|
|
}
|
|
|
|
|
2022-10-16 16:27:17 +00:00
|
|
|
public:
|
|
|
|
class const_iterator {
|
2022-10-19 03:35:06 +00:00
|
|
|
public:
|
2022-10-16 16:27:17 +00:00
|
|
|
typedef T* value_type;
|
|
|
|
|
|
|
|
const_iterator() : current(nullptr) {}
|
2022-10-19 03:35:06 +00:00
|
|
|
const_iterator(const node* begin) : current(begin) {}
|
2022-10-16 16:27:17 +00:00
|
|
|
const_iterator& operator++() {
|
|
|
|
this->current = this->current->x4_next;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
const_iterator operator++(int) const { return const_iterator(this->current->x4_next); }
|
|
|
|
const_iterator& operator--() {
|
|
|
|
this->current = this->current->x0_prev;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
const_iterator operator--(int) const { return const_iterator(this->current->x0_prev); }
|
2022-10-20 16:32:57 +00:00
|
|
|
const T* get_pointer() const { return current->get_value(); }
|
|
|
|
const T& operator*() const { return *current->get_value(); }
|
|
|
|
const T* operator->() const { return current->get_value(); }
|
2022-10-16 16:27:17 +00:00
|
|
|
bool operator==(const const_iterator& other) const { return current == other.current; }
|
|
|
|
bool operator!=(const const_iterator& other) const { return current != other.current; }
|
|
|
|
|
2022-10-20 14:25:08 +00:00
|
|
|
const node* get_node() const { return current; }
|
|
|
|
|
2022-10-16 16:27:17 +00:00
|
|
|
protected:
|
|
|
|
const node* current;
|
|
|
|
};
|
|
|
|
|
2022-10-19 03:35:06 +00:00
|
|
|
class iterator : const_iterator {
|
2022-10-16 16:27:17 +00:00
|
|
|
public:
|
|
|
|
typedef T* value_type;
|
|
|
|
|
|
|
|
iterator() : const_iterator(nullptr) {}
|
2022-10-19 03:35:06 +00:00
|
|
|
iterator(node* begin) : const_iterator(begin) {}
|
2022-10-16 16:27:17 +00:00
|
|
|
iterator& operator++() {
|
|
|
|
this->current = this->current->x4_next;
|
|
|
|
return *this;
|
|
|
|
}
|
2022-10-20 14:25:08 +00:00
|
|
|
iterator operator++(int) {
|
|
|
|
node* cur = this->current;
|
|
|
|
this->current = this->current->x4_next;
|
|
|
|
return cur;
|
2022-10-19 03:35:06 +00:00
|
|
|
}
|
2022-10-16 16:27:17 +00:00
|
|
|
iterator& operator--() {
|
|
|
|
this->current = this->current->x0_prev;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
iterator operator--(int) { return iterator(this->curent->x0_prev); }
|
|
|
|
T* get_pointer() const { return current->get_value(); }
|
|
|
|
T& operator*() const { return *current->get_value(); }
|
|
|
|
T* operator->() const { return current->get_value(); }
|
|
|
|
bool operator==(const iterator& other) const { return current == other.current; }
|
|
|
|
bool operator!=(const iterator& other) const { return current != other.current; }
|
2022-10-19 03:35:06 +00:00
|
|
|
|
2022-12-01 16:19:53 +00:00
|
|
|
node* get_node() const { return current; }
|
|
|
|
|
2022-10-16 16:27:17 +00:00
|
|
|
protected:
|
|
|
|
node* current;
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
2022-04-10 00:17:06 +00:00
|
|
|
Alloc x0_allocator;
|
|
|
|
node* x4_start;
|
|
|
|
node* x8_end;
|
2022-10-19 03:35:06 +00:00
|
|
|
node* xc_empty_prev;
|
|
|
|
node* x10_empty_next;
|
2022-11-10 06:50:18 +00:00
|
|
|
int x14_count;
|
2022-04-10 00:17:06 +00:00
|
|
|
};
|
2022-10-16 16:27:17 +00:00
|
|
|
|
2022-11-27 00:26:12 +00:00
|
|
|
template < typename T, typename Alloc >
|
|
|
|
list< T, Alloc >::~list() {
|
|
|
|
node* cur = x4_start;
|
|
|
|
while (cur != x8_end) {
|
|
|
|
node* it = cur;
|
|
|
|
node* next = cur->get_next();
|
|
|
|
cur = next;
|
|
|
|
destroy(it);
|
|
|
|
x0_allocator.deallocate(it);
|
2022-11-15 13:45:15 +00:00
|
|
|
}
|
2022-11-27 00:26:12 +00:00
|
|
|
}
|
2022-11-15 13:45:15 +00:00
|
|
|
|
2022-12-01 16:19:53 +00:00
|
|
|
|
|
|
|
template < typename T, typename Alloc >
|
|
|
|
typename list< T, Alloc >::node* list< T, Alloc >::erase(node* node) {
|
|
|
|
typename list< T, Alloc >::node* result = node->get_next();
|
|
|
|
if (node == x4_start) {
|
|
|
|
x4_start = result;
|
|
|
|
}
|
|
|
|
node->get_prev()->set_next(node->get_next());
|
|
|
|
node->get_next()->set_prev(node->get_prev());
|
|
|
|
destroy(node);
|
|
|
|
x0_allocator.deallocate(node);
|
|
|
|
x14_count--;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-04-10 00:17:06 +00:00
|
|
|
} // namespace rstl
|
|
|
|
|
2022-10-09 05:13:17 +00:00
|
|
|
#endif // _RSTL_LIST
|