/**************************************************************************** PROJECT: FlowerSoft C++ library FILE : list.cc --*/ #include #include "list.h" #include "citerate.h" /**************************************************************************** class List --*/ void List::_clear() { Link* l = last; // checked in clear(), should never happen if ( l == ZEROLINK ) return; do { Link* ll = l; #if 0 // take no risk // def __TURBOC__ delete &ll->object; #else delete &( ll->object ); #endif l = l->next; delete ll; } while( l != last ); last = ZEROLINK; // list is empty _count = 0; } /* insert() inserts an object at the top of the list, where it will be first get()ten and last remove()d. next() moves the top object to the end of the list. +-->A-->+ +-->A-->B-->+ +-->A-->C-->B-->+ +-->A-->C-->B-->+ |___l___| |___l_______| |___l___________| |_______l_______| insert( A ) insert( B ) insert( C ) next() --*/ Object& List::get() { if ( last == ZEROLINK ) { error( "get from empty list", __FILE__, __LINE__ ); return NOOBJECT; } else { Link* f = last->next; Object& r( f->object ); if ( f == last ) last = ZEROLINK; else last->next = f->next; if ( *f != r ) delete f; // if Object isn't Link itself _count--; return r; } } //use as put to get backwards linked list int List::insert( Object& object ) { if ( last != ZEROLINK ) last->next = new Link( object, *last->next ); else #if 0 // take no risk // ndef ASSIGN_LEFT_TO_RIGHT last->next = last = new Link( object, *ZEROLINK ); #else { last = new Link( object, *ZEROLINK ); last->next = last; } #endif _count++; return 0; } /* next() moves top to bottom and returns new top see insert and put --*/ Object& List::next() { if ( last != ZEROLINK ) { last = last->next; return last->next->object; } else return NOOBJECT; } /* previous() moves bottom to top and returns new top is time expensive for long lists --*/ Object& List::previous() { if ( last != ZEROLINK ) { Link* beforeLast = last->next; while ( beforeLast->next != last ) beforeLast = beforeLast->next; last = beforeLast; return last->next->object; } else return NOOBJECT; } void List::printOn( ostream& os ) const { if ( last == ZEROLINK ) return; const Link* link = last; do { link = ( const Link* ) link->next; os << link->object; } while ( link != last ); } /* put() appends an object to the end of the list, where it will be last get()ten and first remove()d. next() appends the top object to the end of the list. +-->A-->+ +-->B-->A-->+ +-->C-->A-->B-->+ +-->A-->B-->C-->+ |___l___| |___l_______| |___l___________| |___l___________| put( A ) put( B ) put( C ) next() --*/ int List::put( Object& object ) { if ( last != ZEROLINK ) #if 0 // take no risk // ndef ASSIGN_LEFT_TO_RIGHT last = last->next = new Link( object, *last->next ); #else { last->next = new Link( object, *last->next ); last = last->next; } #endif else { last = new Link( object, *ZEROLINK ); last->next = last; } _count++; return 0; } int List::putList( List& list ) { if ( list == NOLIST ) return 1; while ( list.count() ) put ( list.get() ); return 0; } Object& List::remove() { previous(); Object& object = get(); next(); return object; } void List::each( ITERATE action, void* parameters ) { ListIterator links( *this ); while( links ) links++.each( action, parameters ); } void List::each( ITERATE_CONST action, void* parameters ) const { ListConstIterator links( *this ); while( links ) links++.each( action, parameters ); } Object& List::first( ITERATE_TEST test, void *parameters ) { ListIterator links( *this ); while( links ) #if 1 { Object& object = links++.first( test, parameters ); if ( object != NOOBJECT ) return object; } #else if ( Object& object = links++.first( test, parameters ) != NOOBJECT ) return object; #endif return NOOBJECT; } //-- class List //