forked from KolibriOS/kolibrios
193 lines
5.2 KiB
Plaintext
193 lines
5.2 KiB
Plaintext
|
#ifndef _LIST_INCLUDED
|
||
|
#define _LIST_INCLUDED
|
||
|
#include <stdlib.h>
|
||
|
namespace std
|
||
|
{
|
||
|
struct __list_node_base
|
||
|
{
|
||
|
__list_node_base* prev;
|
||
|
__list_node_base* next;
|
||
|
};
|
||
|
template <class T> struct __list_node : __list_node_base
|
||
|
{
|
||
|
T data;
|
||
|
__list_node(const T& d):data(d){}
|
||
|
};
|
||
|
template <class T> class list
|
||
|
{
|
||
|
__list_node_base head; // head.prev = end, head.next = start
|
||
|
unsigned _size;
|
||
|
public:
|
||
|
list():_size(0) {head.prev=head.next=&head;}
|
||
|
~list() {clear();}
|
||
|
void clear()
|
||
|
{
|
||
|
__list_node<T>* a =
|
||
|
static_cast<__list_node<T>*>(head.next);
|
||
|
while (a!=&head)
|
||
|
{
|
||
|
__list_node<T>* b =
|
||
|
static_cast<__list_node<T>*>(a->next);
|
||
|
delete a;
|
||
|
a = b;
|
||
|
}
|
||
|
head.prev = head.next = &head;
|
||
|
_size = 0;
|
||
|
}
|
||
|
class iterator
|
||
|
{
|
||
|
public:
|
||
|
__list_node_base* cur;
|
||
|
friend class list;
|
||
|
iterator(){}
|
||
|
iterator(__list_node_base*c):cur(c){}
|
||
|
iterator(const iterator& it):cur(it.cur){}
|
||
|
iterator& operator++()
|
||
|
{cur=cur->next;return *this;}
|
||
|
iterator operator++(int)
|
||
|
{iterator tmp(*this);cur=cur->next;return tmp;}
|
||
|
iterator& operator--()
|
||
|
{cur=cur->prev;return *this;}
|
||
|
iterator operator--(int)
|
||
|
{iterator tmp(*this);cur=cur->prev;return tmp;}
|
||
|
bool operator!=(const iterator& it)
|
||
|
{return cur!=it.cur;}
|
||
|
bool operator==(const iterator& it)
|
||
|
{return cur==it.cur;}
|
||
|
T& operator*()
|
||
|
{return static_cast<__list_node<T>*>(cur)->data;}
|
||
|
T* operator->() {return &**this;}
|
||
|
};
|
||
|
class const_iterator
|
||
|
{
|
||
|
const __list_node_base* cur;
|
||
|
friend class list;
|
||
|
public:
|
||
|
const_iterator(){}
|
||
|
const_iterator(const __list_node_base*c):cur(c){}
|
||
|
const_iterator(const const_iterator& it):cur(it.cur){}
|
||
|
const_iterator(const iterator& it):cur(it.cur){}
|
||
|
const_iterator& operator++()
|
||
|
{cur=cur->next;return *this;}
|
||
|
const_iterator operator++(int)
|
||
|
{const_iterator tmp(*this);cur=cur->next;return tmp;}
|
||
|
const_iterator& operator--()
|
||
|
{cur=cur->prev;return *this;}
|
||
|
const_iterator operator--(int)
|
||
|
{const_iterator tmp(*this);cur=cur->prev;return tmp;}
|
||
|
bool operator!=(const const_iterator& it)
|
||
|
{return cur!=it.cur;}
|
||
|
bool operator==(const const_iterator& it)
|
||
|
{return cur==it.cur;}
|
||
|
const T& operator*()
|
||
|
{return static_cast<const __list_node<T>*>(cur)->data;}
|
||
|
const T* operator->() {return &**this;}
|
||
|
};
|
||
|
iterator erase(iterator it)
|
||
|
{
|
||
|
if (it==end()) return it;
|
||
|
it.cur->prev->next = it.cur->next;
|
||
|
it.cur->next->prev = it.cur->prev;
|
||
|
iterator res(it.cur->next);
|
||
|
delete static_cast<__list_node<T>*>(it.cur);
|
||
|
--_size;
|
||
|
return res;
|
||
|
}
|
||
|
iterator erase(iterator first, iterator last)
|
||
|
{
|
||
|
while (first!=last)
|
||
|
first=erase(first);
|
||
|
return first;
|
||
|
}
|
||
|
void pop_front(void) {erase(begin());}
|
||
|
class reverse_iterator
|
||
|
{
|
||
|
__list_node_base* cur;
|
||
|
friend class list;
|
||
|
public:
|
||
|
reverse_iterator(){}
|
||
|
reverse_iterator(__list_node_base*c):cur(c){}
|
||
|
reverse_iterator(const reverse_iterator& it):
|
||
|
cur(it.cur){}
|
||
|
reverse_iterator& operator++()
|
||
|
{cur=cur->prev;return *this;}
|
||
|
reverse_iterator operator++(int)
|
||
|
{reverse_iterator tmp(*this);
|
||
|
cur=cur->prev;return tmp;}
|
||
|
bool operator!=(const reverse_iterator& it)
|
||
|
{return cur!=it.cur;}
|
||
|
bool operator==(const reverse_iterator& it)
|
||
|
{return cur==it.cur;}
|
||
|
T& operator*()
|
||
|
{return static_cast<__list_node<T>*>(cur)->data;}
|
||
|
};
|
||
|
class const_reverse_iterator
|
||
|
{
|
||
|
const __list_node_base* cur;
|
||
|
friend class list;
|
||
|
public:
|
||
|
const_reverse_iterator(){}
|
||
|
const_reverse_iterator(const __list_node_base*c):cur(c){}
|
||
|
const_reverse_iterator(const const_reverse_iterator& it):
|
||
|
cur(it.cur){}
|
||
|
const_reverse_iterator& operator++()
|
||
|
{cur=cur->prev;return *this;}
|
||
|
const_reverse_iterator operator++(int)
|
||
|
{const_reverse_iterator tmp(*this);
|
||
|
cur=cur->prev;return tmp;}
|
||
|
bool operator!=(const const_reverse_iterator& it)
|
||
|
{return cur!=it.cur;}
|
||
|
bool operator==(const const_reverse_iterator& it)
|
||
|
{return cur==it.cur;}
|
||
|
const T& operator*()
|
||
|
{return static_cast<__list_node<T>*>(cur)->data;}
|
||
|
};
|
||
|
void push_front(const T& x)
|
||
|
{
|
||
|
__list_node<T>* a = new __list_node<T>(x);
|
||
|
a->next = head.next;
|
||
|
a->prev = &head;
|
||
|
head.next = a;
|
||
|
a->next->prev = a;
|
||
|
++_size;
|
||
|
}
|
||
|
void push_back(const T& x)
|
||
|
{
|
||
|
__list_node<T>* a = new __list_node<T>(x);
|
||
|
a->next = &head;
|
||
|
a->prev = head.prev;
|
||
|
head.prev = a;
|
||
|
a->prev->next = a;
|
||
|
++_size;
|
||
|
}
|
||
|
iterator begin() {return iterator(head.next);}
|
||
|
const_iterator begin() const {return const_iterator(head.next);}
|
||
|
iterator end() {return iterator(&head);}
|
||
|
const_iterator end() const {return const_iterator(&head);}
|
||
|
reverse_iterator rbegin()
|
||
|
{return reverse_iterator(head.prev);}
|
||
|
reverse_iterator rend() {return reverse_iterator(&head);}
|
||
|
void remove(const T& x)
|
||
|
{
|
||
|
__list_node<T>* a =
|
||
|
static_cast<__list_node<T>*>(head.next);
|
||
|
while (a!=&head)
|
||
|
{
|
||
|
__list_node<T>* b =
|
||
|
static_cast<__list_node<T>*>(a->next);
|
||
|
if (a->data==x)
|
||
|
{
|
||
|
a->prev->next = a->next;
|
||
|
a->next->prev = a->prev;
|
||
|
delete a;
|
||
|
--_size;
|
||
|
}
|
||
|
a=b;
|
||
|
}
|
||
|
}
|
||
|
unsigned size() const {return _size;}
|
||
|
bool empty() const {return _size==0;}
|
||
|
};
|
||
|
}
|
||
|
#endif
|