// // // simplified list class // // Described in Chapter 9 of // Data Structures in C++ using the STL // Published by Addison-Wesley, 1997 // Written by Tim Budd, budd@cs.orst.edu // Oregon State University // // template class listIterator { typedef listIterator iterator; public: // constructor listIterator (list * tl, link * cl) : theList(tl), currentLink(cl) { } // iterator protocol T & operator * () { return currentLink->value; } void operator = (iterator & rhs) { theList = rhs.theList; currentLink = rhs.currentLink; } bool operator == (const iterator rhs) const { return currentLink == rhs.currentLink; } iterator & operator ++ (int) { currentLink = currentLink->nextLink; return * this; } iterator operator ++ (); iterator & operator -- (int) { currentLink = currentLink->prevLink; return * this; } iterator operator -- (); protected: list * theList; link * currentLink; friend class list; }; template class list { public: // type definitions typedef T value_type; typedef listIterator iterator; // constructor and destructor list () : firstLink(0), lastLink(0) { } list (list & x) : firstLink(0), lastLink(0) { } ~ list (); // operations bool empty () { return firstLink == 0; } int size(); T & back () { return lastLink->value; } T & front () { return firstLink->value; } void push_front(T &); void push_back(T &); void pop_front (); void pop_back (); iterator begin () { return iterator (this, firstLink); } iterator end () { return iterator (this, 0); } void sort (); void insert (iterator &, T &); void erase (iterator & itr) { erase (itr, itr); } void erase (iterator &, iterator &); protected: link * firstLink; link * lastLink; }; template class link { private: link (T & v) : value(v), nextLink(0), prevLink(0) { } T value; link * nextLink; link * prevLink; // allow lists to see element values friend class list; friend class listIterator; }; template int list::size () // count number of elements in collection { int counter = 0; for (link * ptr = firstLink; ptr != 0; ptr = ptr->nextLink) counter++; return counter; } template void list::push_front (T & newValue) // add a new value to the front of a list { link * newLink = new link (newValue); if (empty()) firstLink = lastLink = newLink; else { firstLink->prevLink = newLink; newLink->nextLink = firstLink; firstLink = newLink; } } template void list::pop_front() // remove first element from linked list { link * save = firstLink; firstLink = firstLink->nextLink; if (firstLink != 0) firstLink->prevLink = 0; else lastLink = 0; delete save; } template list::~list () // remove each element from the list { link * first = firstlink; while (first != 0) { link * next = first->nextLink; delete first; first = next; } } template listIterator listIterator::operator ++ () // postfix form of increment { // clone, then increment, return clone listIterator clone (theList, currentLink); currentLink = currentLink->nextLink; return clone; } template void list::insert (listIterator & itr, T & value) // insert a new element into the middle of a linked list { link * newLink = new link(value); link * current = itr->currentLink; newLink->nextLink = current; newLink->prevLink = current->prevLink; current->prevLink = newLink; current = newLink->prevLink; if (current != 0) current->nextLink = newLink; } template void list::erase (listIterator & start, listIterator & stop) // remove values from the range of elements { link * first = start.currentLink; link * prev = first->prevLink; link * last = stop.currentLink; if (prev == 0) { // removing initial portion of list firstLink = last; if (last == 0) lastLink = 0; else last->prevLink = 0; } else { prev->nextLink = last; if (last == 0) lastLink = prev; else last->prevLink = prev; } // now delete the values while (start != stop) { listIterator next = start; ++next; delete start.currentLink; start = next; } }