#ifndef LIST__H__ #define LIST__H__ template struct list_node { list_node* next; T data; list_node(T d, list_node* n = 0) : next(n), data(d) { } ~list_node() { } }; template class list_iterator; template class const_list_iterator; template class list { public: typedef list_node node; typedef list_iterator iter; typedef const_list_iterator const_iter; friend class list_iterator; friend class const_list_iterator; list() : head(0), tail(0), cnt(0) { } list(const list&); ~list() { empty(); } unsigned count() const { return cnt; } void empty() { while(head) { node* next = head->next; delete head; head = next; } tail = 0; cnt = 0; } bool append(T data) { node* n = new node(data); if(tail) tail->next = n; else head = n; tail = n; ++cnt; return true; } bool prepend(T data) { head = new node(data, head); if(!tail) tail = head; ++cnt; return true; } bool remove(iter&); private: node* head; node* tail; unsigned cnt; }; template class const_list_iterator { friend class list; private: inline void go_next() { prev = curr; if(curr) curr = curr->next; } public: const_list_iterator(const list& l) : lst(l), prev(0), curr(l.head) { } void operator++() { go_next(); } void operator++(int) { go_next(); } T operator*() const { return curr->data; } bool operator!() const { return curr == 0; } operator bool() const { return !operator!(); } private: const list& lst; // g++ 3.2 insists const typename list::node* prev; const typename list::node* curr; }; template list::list(const list& that) : head(0), tail(0), cnt(0) { for(const_iter i = that; i; ++i) append(*i); } template class list_iterator { friend class list; private: inline void go_next() { prev = curr; if(curr) curr = curr->next; } public: list_iterator(list& l) : lst(l), prev(0), curr(l.head) { } void operator++() { go_next(); } void operator++(int) { go_next(); } T operator*() const { return curr->data; } T& operator*() { return curr->data; } bool operator!() const { return curr == 0; } operator bool() const { return !operator!(); } private: list& lst; typename list::node* prev; typename list::node* curr; }; template bool list::remove(list::iter& iter) { if(this != &iter.lst) return false; if(!iter.curr) return false; if(iter.prev) { iter.prev->next = iter.curr->next; if(iter.curr == tail) tail = iter.prev; delete iter.curr; iter.curr = iter.prev->next; } else { head = iter.curr->next; if(!head) tail = 0; delete iter.curr; iter.curr = head; } --cnt; return true; } #endif // LIST__H__