/* * FILE: list.cpp - member function implementations for a List ADT * which uses a linked-list representation */ #include "list.h" template node::node( const item& itm, node* ptr ) { data = itm; link = ptr; } template list::list() { first = last = curr = prev = NULL; count = 0; } template list::~list() { node* doomed; while ( first != NULL ) { doomed = first; first = first->link; delete doomed; } } template void list::insertFirst( const item& itm ) { assert( (first = new node( itm, first )) != NULL ); if ( last == NULL ) { last = first; } count++; // move curr past the node inserted prev = first; curr = prev->link; } template void list::insertLast( const item& itm ) { if ( last == NULL ) { insertFirst( itm ); } else { assert( (last = last->link = new node(itm, NULL)) != NULL ); count++; // move curr past the node inserted node prev = last; curr = NULL; } } template void list::insertBefore( const item& itm ) { if ( size() == 0 || curr == first ) // empty list { insertFirst( itm ); } else { assert( (prev->link = new node( itm, curr )) != NULL ); if ( curr == NULL ) { last = prev->link; } count++; // curr remains just past the inserted node // move prev to inserted node prev = prev->link; } } template void list::insertAfter( const item& itm ) { if ( size() == 0 || curr == last || curr == NULL) { insertLast( itm ); } else { assert( (curr->link = new node( itm, curr->link )) != NULL ); count++; // move curr passed inserted node, keep prev 1 before curr prev = curr->link; curr = prev->link; } } template void list::removeFirst() { assert( size() > 0 ); node* doomed = first; if ( first == last ) { first = last = curr = prev = NULL; } else { first = first->link; prev = NULL; curr = first; } delete doomed; count--; } template void list::removeLast() { node* doomed = last; if ( first == last ) { first = last = curr = prev = NULL; } else { node* tmp; for ( tmp = first; tmp->link != last; tmp = tmp->link ) ; tmp->link = NULL; last = prev = tmp; curr = NULL; } delete doomed; count--; } template void list::removeCurrent() { assert( size() > 0 && curr != NULL ); if ( curr == first ) { removeFirst(); } else if ( curr == last ) { removeLast(); } else { node* doomed = curr; prev->link = curr->link; curr = curr->link; delete doomed; count--; } } template item list::firstValue() { assert( size() > 0 ); return first->data; } template item list::lastValue() { assert( size() > 0 ); return last->data; } template item list::currentValue() { assert( size() > 0 && curr != NULL ); return curr->data; } template int list::size() { return count; } template void list::start() { prev = NULL; curr = first; } template int list::more() { return (curr != NULL); } template void list::advance() { prev = curr; curr = curr->link; } template void list::print() { for ( start(); more(); advance() ) { cout << currentValue() << endl; } } // At this point we include the set of explicit instantiations // required to force the compiler to generate the list class to // store specific types as needed by the application using our class #include "exp.h"