// File: genlist4.C // // Implementation of the GenList class using templates // Version 2: use templates // Version 3: return TYPE values using a reference parameter // add iterator class // Version 4: remove() returns the number of items removed // new and delete operators // throws exceptions #include #include #include #include "errors.h" #include "genlist4.h" //======================================================================== // Definition of ListCell member functions // // Memory Allocation // template void *ListCell::operator new(size_t n) { // new ListCell void *ptr = malloc(n) ; if (ptr == NULL) throw(MemoryError()) ; return ptr ; } template void *ListCell::operator new[](size_t n) { // new array of ListCell void *ptr = malloc(n) ; if (ptr == NULL) throw(MemoryError()) ; return ptr ; } template void ListCell::operator delete(void *ptr) { // free a ListCell free(ptr) ; } template void ListCell::operator delete[](void *ptr) { // free array of ListCell free(ptr) ; } //======================================================================== // Definition of GenList member functions // // Constructor. // template GenList::GenList() { last = &dummy ; len = 0 ; cache_status = dirty ; } // Destructor. Loop through list and delete each cell. // template GenList::~GenList() { ListCell *ptr, *temp ; ptr = dummy.next ; while (ptr != NULL) { temp = ptr->next ; delete ptr ; // destructor for data must do the right thing ptr = temp ; } } // Copy constructor // template GenList::GenList(GenList& L) { *this = L ; } // Assignment operator. Duplicate the list. // template 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 = new ListCell(ptr->data) ; last->next = temp ; last = temp ; len++ ; ptr = ptr->next ; } return *this ; } // Add new item to the end of the list // template void GenList::append(const TYPE& t) { ListCell *newitem = new ListCell(t) ; last->next = newitem ; last = newitem ; len++ ; cache_status = dirty ; } // Add new item to the front of the list // template void GenList::prepend(const TYPE& t) { ListCell *newitem = new ListCell(t) ; newitem->next = dummy.next ; dummy.next = newitem ; if (last == &dummy) last = newitem ; len++ ; cache_status = dirty ; } // Remove item from the front of the list // template int GenList::chop(TYPE &result) { ListCell *ptr ; if (dummy.next == NULL) return false ; 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 ; result = ptr->data ; // uses TYPE assignment delete ptr ; return true ; } // Loop through the list and print each item // template void GenList::print() const { ListCell *ptr ; ptr = dummy.next ; while (ptr != NULL) { cout << ptr->data << " " ; ptr = ptr->next ; } } // Remove every occurrence of an item from the list. // Items are compared using TYPE comparsion operator. // template int GenList::remove(const TYPE& t) { ListCell *ptr, *temp ; int count ; ptr = &dummy ; count = 0 ; while (ptr->next != NULL) { if (ptr->next->data == t) { temp = ptr->next ; ptr->next = temp->next ; delete temp ; len-- ; count++ ; cache_status = dirty ; } else { ptr = ptr->next ; } } if (len == 0) last = &dummy ; return count ; } // Memory Allocation // template void *GenList::operator new(size_t n) { // new List void *ptr = malloc(n) ; if (ptr == NULL) throw(MemoryError()) ; return ptr ; } template void *GenList::operator new[](size_t n) { // new array of List void *ptr = malloc(n) ; if (ptr == NULL) throw(MemoryError()) ; return ptr ; } template void GenList::operator delete(void *ptr) { // free a List free(ptr) ; } template void GenList::operator delete[](void *ptr) { // free array of List free(ptr) ; } //======================================================================== // Definition of Iterator member functions // template Iterator::Iterator(GenList& List) : L(List) // initialize GenList reference, does not copy { cache_ptr = &L.dummy ; // point to first item L.cache_status = L.clean ; // check later if list changed good = true ; } template int Iterator::next(TYPE& result) { if (cache_ptr == NULL) return 0 ; // already at end of list cache_ptr = cache_ptr->next ; if (cache_ptr == NULL) return 0 ; // end of list if (L.cache_status == L.dirty) { // cache invalid good = false ; return 0 ; } result = cache_ptr->data ; // All OK return 1 ; } template int Iterator::set(const TYPE& t) { if (cache_ptr == NULL || L.cache_status == L.dirty) { good = false ; // something went wrong return 0 ; } cache_ptr->data = t ; return 1 ; } // Memory Allocation // template void *Iterator::operator new(size_t n) { // new Iterator void *ptr = malloc(n) ; if (ptr == NULL) throw(MemoryError()) ; return ptr ; } template void *Iterator::operator new[](size_t n) { // new array of Iterator void *ptr = malloc(n) ; if (ptr == NULL) throw(MemoryError()) ; return ptr ; } template void Iterator::operator delete(void *ptr) { // free a Iterator free(ptr) ; } template void Iterator::operator delete[](void *ptr) { // free array of Iterator free(ptr) ; }