// File: genlist.C // // Implementation of the GenList class // // Version: 10/11/98 21:13 pm. // Fixed problems with GenList assignment operator. #include #include #include #include "genlist.h" //======================================================================== // "Local" functions // static void CrashOnNULL(void *, char *) ; static void CrashOnNULL(void *ptr, char *mesg) { if (ptr == NULL) { cerr << "CrashOnNULL: " << mesg <next = next ; return cptr ; } // comparison function, virtual. Nothing to compare in the base class. // int ListCell::cmp(const ListCell& cell) const { #ifndef NDEBUG cerr << "ListCell: Base compare function" << endl ; #endif return 0 ; } // print function, virtual. Nothing to print in base class. // void ListCell::print() const { #ifndef NDEBUG cerr << "ListCell: Base print function" << endl ; #endif return ; } // id function, virtual. Returns &idvar so we can tell different // derived classes apart. // int *ListCell::id() const { #ifndef NDEBUG cerr << "ListCell: id function" << endl ; #endif return &ListCell::idvar ; } //======================================================================== // Definition of GenList member functions // // Constructor. // GenList::GenList() { #ifndef NDEBUG cerr << "GenList constructor, this = " << this << endl ; #endif last = &dummy ; len = 0 ; cache_status = dirty ; } // Destructor. Loop through list and delete each cell. // GenList::~GenList() { ListCell *ptr, *temp ; #ifndef NDEBUG cerr << "GenList destructor, this = " << this << endl ; #endif ptr = dummy.next ; while (ptr != NULL) { temp = ptr->next ; delete ptr ; ptr = temp ; } } // Copy constructor // GenList::GenList(GenList& L) { *this = L ; } // Assignment operator. Duplicate the list. // GenList& GenList::operator=(const GenList& L) { ListCell *ptr, *temp ; // self assignment? if (this == &L) return *this ; // delete old host ptr = dummy.next ; while (ptr != NULL) { temp = ptr->next ; delete ptr ; ptr = temp ; } cache_status = dirty ; last = &dummy ; len = 0 ; // copy L item by item ptr = L.dummy.next ; while (ptr != NULL) { temp = ptr->clone() ; last->next = temp ; last = temp ; len++ ; ptr = ptr->next ; } return *this ; } // Add new item to the end of the list // void GenList::append(const ListCell& cell) { ListCell *newitem = cell.clone() ; last->next = newitem ; last = newitem ; len++ ; cache_status = dirty ; } // Add new item to the front of the list // void GenList::prepend(const ListCell& cell) { ListCell *newitem = cell.clone() ; newitem->next = dummy.next ; dummy.next = newitem ; if (last == &dummy) last = newitem ; len++ ; cache_status = dirty ; } // Remove item from the front of the list // ListCell *GenList::chop() { ListCell *ptr, *result ; if (dummy.next == NULL) return NULL ; ptr = dummy.next ; dummy.next = ptr->next ; // check if last item is removed if (dummy.next == NULL) last = &dummy ; // update info len-- ; cache_status = dirty ; ptr->next = NULL ; return ptr ; } // Loop through the list and print each item // void GenList::print() const { ListCell *ptr ; ptr = dummy.next ; while (ptr != NULL) { ptr->print() ; ptr = ptr->next ; } } // Remove every occurrence of an item from the list. // Items are compared using the client supplied comparsion function. // The comparison function should return values similar to strcmp(a,b): // <0 if a < b. // =0 if a == b // >0 if a > b // void GenList::remove(const ListCell& cell) { ListCell *ptr, *temp ; ptr = &dummy ; while (ptr->next != NULL) { if (ptr->next->cmp(cell) == 0) { temp = ptr->next ; ptr->next = temp->next ; delete temp ; len-- ; cache_status = dirty ; } else { ptr = ptr->next ; } } if (len == 0) last = &dummy ; }