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