// -------------------------------------------------------------------------- // Linear Containers // A. Fischer June 12, 2001 file: linear.hpp // -------------------------------------------------------------------------- #pragma once #include #include "container.hpp" #include "cell.hpp" using namespace std; template class Linear: public Container { protected: // ------------------------------------------------------------- Cell* head; // This is a dummy header for the list. private: // ------------------------------------------------------------- Cell* here; // Cursor for traversing the container. Cell* prior; // Trailing pointer for traversing the container. protected: // ------------------------------------------------------------- Linear(): head(new Cell), here( NULL ), prior( head ) {} virtual ~Linear (); void reset() { prior = head; here = head->next; } bool end() const { return here == NULL; } void operator ++(); virtual void insert( Cell* cp ); virtual void focus() = 0; Cell* remove(); bool operator< ( Cell* cp ) { return cp->data->key() < here->data->key(); } bool operator< ( KeyType k ){ return *here->data < k; } bool operator== ( KeyType k ){ return *here->data == k; } public: // -------------------------------------------------------------- void put(T * ep) { if (ep) insert( new Cell(ep) ); } T* pop(); T* peek() { focus(); return *here; } virtual ostream& print( ostream& out ); }; template inline ostream& operator<<(ostream& out, Linear& s) {return s.print(out); } // ======================================================================== // Implementation of template methods // ------------------------------------------------------------------------ template Linear::~Linear () { for (reset(); !end(); ++*this) { delete prior->data; delete prior; } delete prior->data; delete prior; } // ------------------------------ Move index to next item in the container. template void Linear::operator ++() { if (!end() ){ prior = here; here = here->next; } } // ---------------- Put an item into the container between prior and here. // ------------- Assumes that here and prior have been positioned already. template void Linear::insert(Cell* cp) { cp->next = here; here = prior->next = cp; } // ---------------- Take an item out of the container. Like pop or dequeue. // -- Assumes that here and prior have been positioned to the desired item. template Cell* Linear::remove() { if (! here ) return NULL; Cell* temp = here; // Grab cell to remove. here = prior->next = temp->next; // Link around it. return temp; } // ------------------------------------ Remove a Cell and return its T. template T* Linear::pop(){ focus(); // Set here and prior for deletion point. Cell* temp = remove(); // Remove first real cell on list. if (!temp) return NULL; // Check for empty condition. T* answer = *temp; // Using cast coercion from Cell to T. delete temp; // Take contents out of cell, delete Cell. return answer; // Return data item. } // ---------------------------------------- Print the container's contents. template ostream& Linear::print (ostream& out ) { out << " <[\n"; for (reset(); !end(); ++*this) out << "\t" <<*here; return out << " ]>\n"; };