/* emacs edit mode for this file is -*- C++ -*- */ #include template ListItem::ListItem( const ListItem& i ) { next = i.next; prev = i.prev; item = i.item; } template ListItem::ListItem( const T& t, ListItem* n, ListItem* p ) { next = n; prev = p; item = new T( t ); } template ListItem::ListItem( T* t, ListItem* n, ListItem* p ) { next = n; prev = p; item = t; } template ListItem::~ListItem() { delete item; } template ListItem& ListItem::operator=( const ListItem& i ) { if ( this != &i ) { next = i.next; prev = i.prev; item = i.item; } return *this; } template ListItem* ListItem::getNext() { return next; } template ListItem* ListItem::getPrev() { return prev; } template T& ListItem::getItem() { return *item; } #ifndef NOSTREAMIO template void ListItem::print( OSTREAM & os ) { if ( item ) os << *item; else os << "(no item)"; } #endif /* NOSTREAMIO */ template List::List() { first = last = 0; _length = 0; } template List::List( const List& l ) { ListItem* cur = l.last; if ( cur ) { first = new ListItem( *(cur->item), 0, 0 ); last = first; cur = cur->prev; while ( cur ) { first = new ListItem( *(cur->item), first, 0 ); first->next->prev = first; cur = cur->prev; } _length = l._length; } else { first = last = 0; _length = 0; } } template List::List( const T& t ) { first = last = new ListItem( t, 0, 0 ); _length = 1; } template List::~List() { ListItem *dummy; while ( first ) { dummy = first; first = first->next; delete dummy; } } template List& List::operator=( const List& l ) { if ( this != &l ) { ListItem *dummy; while ( first ) { dummy = first; first = first->next; delete dummy; } ListItem* cur = l.last; if ( cur ) { first = new ListItem( *(cur->item), 0, 0 ); last = first; cur = cur->prev; while ( cur ) { first = new ListItem( *(cur->item), first, 0 ); first->next->prev = first; cur = cur->prev; } _length = l._length; } else { first = last = 0; _length = 0; } _length = l._length; } return *this; } template void List::insert ( const T& t ) { first = new ListItem( t, first, 0 ); if ( last ) first->next->prev = first; last = ( last ) ? last : first; _length++; } template void List::insert ( const T& t, int (*cmpf)( const T&, const T& ) ) { if ( ! first || cmpf( *first->item, t ) > 0 ) insert( t ); else if ( cmpf( *last->item, t ) < 0 ) append( t ); else { ListItem * cursor = first; int c; while ( (c = cmpf( *cursor->item, t )) < 0 ) cursor = cursor->next; if ( c == 0 ) *cursor->item = t; else { cursor = cursor->prev; cursor->next = new ListItem( t, cursor->next, cursor ); cursor->next->next->prev = cursor->next; _length++; } } } template void List::insert ( const T& t, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) ) { if ( ! first || cmpf( *first->item, t ) > 0 ) insert( t ); else if ( cmpf( *last->item, t ) < 0 ) append( t ); else { ListItem * cursor = first; int c; while ( (c = cmpf( *cursor->item, t )) < 0 ) cursor = cursor->next; if ( c == 0 ) insf( *cursor->item, t ); else { cursor = cursor->prev; cursor->next = new ListItem( t, cursor->next, cursor ); cursor->next->next->prev = cursor->next; _length++; } } } template void List::append ( const T& t ) { last = new ListItem( t, 0, last ); if ( first ) last->prev->next = last; first = ( first ) ? first : last; _length++; } template int List::isEmpty() const { return ( first == 0 ); } template int List::length() const { return _length; } template T List::getFirst() const { ASSERT( first, "List: no item available" ); return first->getItem(); } template void List::removeFirst() { if ( first ) { _length--; if ( first == last ) { delete first; first = last = 0; } else { ListItem *dummy = first; first->next->prev = 0; first = first->next; delete dummy; } } } template T List::getLast() const { ASSERT( first, "List: no item available" ); return last->getItem(); } template void List::removeLast() { if ( last ) { _length--; if ( first == last ) { delete last; first = last = 0; } else { ListItem *dummy = last; last->prev->next = 0; last = last->prev; delete dummy; } } } template void List::sort( int (*swapit) ( const T&, const T& ) ) { if ( first != last ) { int swap; do { swap = 0; ListItem *cur = first; while ( cur->next ) { if ( swapit( *(cur->item), *(cur->next->item) ) ) { T* dummy = cur->item; cur->item = cur->next->item; cur->next->item = dummy; swap = 1; } cur = cur->next; } } while (swap); } } #ifndef NOSTREAMIO template void List::print ( OSTREAM & os ) const { ListItem *cur = first; os << "( "; while ( cur ) { cur->print( os ); if ( (cur = cur->getNext()) ) os << ", "; } os << " )"; } #endif /* NOSTREAMIO */ template ListIterator::ListIterator() { theList = 0; current = 0; } template ListIterator::ListIterator ( const ListIterator & i ) { theList = i.theList; current = i.current; } template ListIterator::ListIterator ( const List & l ) { theList = (List*)&l; current = l.first; } template ListIterator::~ListIterator() { } template ListIterator& ListIterator::operator= ( const ListIterator & I ) { if ( this != &I ) { theList = I.theList; current = I.current; } return *this; } template ListIterator& ListIterator::operator= ( const List & l ) { theList = (List*)&l; current = l.first; return *this; } template T& ListIterator::getItem () const { ASSERT( current, "ListIterator: no item available" ); return current->getItem(); } template int ListIterator::hasItem () { return current != 0; } template void ListIterator::operator++ () { if ( current ) current = current->next; } template void ListIterator::operator-- () { if ( current ) current = current->prev; } template void ListIterator::operator++ ( int ) { if ( current ) current = current->next; } template void ListIterator::operator-- ( int ) { if ( current ) current = current->prev; } template void ListIterator::firstItem () { current = theList->first; } template void ListIterator::lastItem () { current = theList->last; } template void ListIterator::insert ( const T & t ) { if ( current ) { if ( ! current->prev ) theList->insert( t ); else { current->prev = new ListItem( t, current, current->prev ); current->prev->prev->next = current->prev; theList->_length++; } } } template void ListIterator::append ( const T & t ) { if ( current ) { if ( ! current->next ) theList->append( t ); else { current->next = new ListItem( t, current->next, current ); current->next->next->prev = current->next; theList->_length++; } } } template void ListIterator::remove ( int moveright ) { if ( current ) { ListItem *dummynext = current->next, *dummyprev = current->prev; if ( current->prev ) { current->prev->next = current->next; if ( current->next ) current->next->prev = current->prev; else theList->last = current->prev; delete current; current = ( moveright ) ? dummynext : dummyprev; } else { if ( current->next ) current->next->prev = 0; theList->first = current->next; delete current; current = ( moveright ) ? dummynext : dummyprev; } theList->_length--; } } #ifndef NOSTREAMIO template OSTREAM& operator<<( OSTREAM & os, const List & l ) { l.print( os ); return os; } #endif /* NOSTREAMIO */ template List Union ( const List & F, const List & G ) { List L = G; ListIterator i, j; T f; bool iselt; for ( i = F; i.hasItem(); i++ ) { f = i.getItem(); iselt = false; j = G; while ( ( ! iselt ) && j.hasItem() ) { iselt = f == j.getItem(); j++; } if ( ! iselt ) L.append( f ); } return L; } template List Union ( const List & F, const List & G, int (*cmpf)( const T&, const T& ), void (*insf)( T&, const T& ) ) { List L = G; ListIterator i; for ( i = F; i.hasItem(); ++i ) L.insert( i.getItem(), cmpf, insf ); return L; } template List Difference ( const List & F, const List & G ) { List L; ListIterator i, j; T f; int found; for ( i = F; i.hasItem(); ++i ) { f = i.getItem(); found = 0; for ( j = G; j.hasItem() && (!found); ++j ) found = f == j.getItem(); if ( ! found ) L.append( f ); } return L; } template T prod ( const List & F ) { ListIterator i; T p = 1; for ( i = F; i.hasItem(); i++ ) p = p * i.getItem(); return p; } template bool find (const List & F, const T& t) { if (F.length() == 0) return false; ListIterator J= F; while (J.hasItem()) { if (J.getItem() == t) return true; J++; } return false; }