oscar64/include/opp/list.h

371 lines
5.8 KiB
C++

#ifndef OPP_LIST
#define OPP_LIST
namespace opp
{
template <class T>
class listhead
{
public:
listnode<T> * succ, * pred;
listhead()
{
succ = (listnode<T> *)this;
pred = (listnode<T> *)this;
}
};
template <class T>
class listnode : public listhead<T>
{
public:
T data;
listnode(const T & t) : data(t) {}
listnode(T && t) : data(t) {}
};
template <class T>
class list_iterator
{
public:
listnode<T> * node;
public:
list_iterator(void) : node(nullptr) {}
list_iterator(listnode<T> * n) : node(n) {}
list_iterator(const list_iterator & li) : node(li.node) {}
list_iterator & operator=(const list_iterator & li)
{
node = li.node;
return *this;
}
T & operator*()
{
return node->data;
}
T * operator->()
{
return &(node->data);
}
list_iterator & operator++(void)
{
node = node->succ;
return *this;
}
list_iterator operator++(int)
{
listnode<T> * n = node;
node = node->succ;
return list_iterator(n);
}
list_iterator & operator+=(int n)
{
while (n--)
node = node->succ;
return *this;
}
list_iterator & operator--(void)
{
node = node->pred;
return *this;
}
list_iterator operator++(int)
{
listnode<T> * n = node;
node = node->pred;
return list_iterator(n);
}
list_iterator & operator-=(int n)
{
while (n--)
node = node->pred;
return *this;
}
bool operator==(const list_iterator & li)
{
return node == li.node;
}
bool operator!=(const list_iterator & li)
{
return node != li.node;
}
};
template <class T>
class list
{
private:
typedef listnode<T> ln;
listhead<T> head;
public:
typedef T element_type;
typedef list_iterator<T> iterator_type;
list(void)
{}
list(const list & l);
list(list && l)
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
}
list & operator=(const list & l);
list & operator=(list && l)
{
head.succ = l.head.succ;
head.pred = l.head.pred;
head.succ->pred = (listnode<T> *)&head;
head.pred->succ = (listnode<T> *)&head;
l.head.succ = (listnode<T> *)&(l.head);
l.head.pred = (listnode<T> *)&(l.head);
return *this;
}
~list(void)
{
listnode<T> * n = head.succ;
while (n != &head)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
}
list_iterator<T> begin(void)
{
return list_iterator<T>(head.succ);
}
list_iterator<T> end(void)
{
return list_iterator<T>((listnode<T> *)&head);
}
T & front(void)
{
return head.succ->data;
}
const T & front(void) const
{
return head.succ->data;
}
T & back(void)
{
return head.pred->data;
}
const T & back(void) const
{
return head.pred->data;
}
list_iterator<T> erase(list_iterator<T> it);
list_iterator<T> erase(list_iterator<T> first, list_iterator<T> last);
void pop_front(void);
void pop_back(void);
void push_front(const T & t);
void push_front(T && t);
void push_back(const T & t);
void push_back(T && t);
void clear(void);
void append(const list & l);
list_iterator<T> insert(list_iterator<T> it, const T & t);
list_iterator<T> insert(list_iterator<T> it, T && t);
};
template <class T>
list<T>::list(const list<T> & l)
{
append(l);
}
template <class T>
list<T> & list<T>::operator=(const list<T> & l)
{
if (&l != this)
{
clear();
append(l);
}
return *this;
}
template <class T>
void list<T>::pop_front(void)
{
listnode<T> * n = head.succ;
head.succ = n->succ;
n->succ->pred = (listnode<T> *)&head;
delete n;
}
template <class T>
void list<T>::pop_back(void)
{
listnode<T> * n = head.pred;
head.pred = n->pred;
n->pred->succ = (listnode<T> *)&head;
delete n;
}
template <class T>
void list<T>::push_front(const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->pred = (listnode<T> *)&head;
n->succ = head.succ;
head.succ->pred = n;
head.succ = n;
}
template <class T>
void list<T>::push_front(T && t)
{
listnode<T> * n = new listnode<T>(t);
n->pred = (listnode<T> *)&head;
n->succ = head.succ;
head.succ->pred = n;
head.succ = n;
}
template <class T>
void list<T>::push_back(const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = (listnode<T> *)&head;
n->pred = head.pred;
head.pred->succ = n;
head.pred = n;
}
template <class T>
void list<T>::push_back(T && t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = (listnode<T> *)&head;
n->pred = head.pred;
head.pred->succ = n;
head.pred = n;
}
template <class T>
list_iterator<T> list<T>::erase(list_iterator<T> it)
{
listnode<T> * n = it.node;
listnode<T> * s = n->succ;
n->succ->pred = n->pred;
n->pred->succ = n->succ;
delete n;
return list_iterator<T>(s);
}
template <class T>
list_iterator<T> list<T>::erase(list_iterator<T> first, list_iterator<T> last)
{
listnode<T> * n = first.node;
listnode<T> * s = last.node;
n->pred->succ = s;
s->pred = n->pred;
while (n != s)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
return list_iterator<T>(s);
}
template <class T>
list_iterator<T> list<T>::insert(list_iterator<T> it, const T & t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = it.node;
n->pred = it.node->pred;
it.node->pred->succ = n;
it.node->pred = n;
return list_iterator<T>(n);
}
template <class T>
list_iterator<T> list<T>::insert(list_iterator<T> it, T && t)
{
listnode<T> * n = new listnode<T>(t);
n->succ = it.node;
n->pred = it.node->pred;
it.node->pred->succ = n;
it.node->pred = n;
return list_iterator<T>(n);
}
template <class T>
void list<T>::clear(void)
{
listnode<T> * n = head.succ;
while (n != &head)
{
listnode<T> * m = n->succ;
delete n;
n = m;
}
head.succ = (listnode<T> *)&head;
head.pred = (listnode<T> *)&head;
}
template <class T>
void list<T>::append(const list<T> & l)
{
listnode<T> * n = l.head.succ;
while (n != &(l.head))
{
push_back(n->data);
n = n->succ;
}
}
}
#endif