// generictable.cc // // Generic Data Structures // Tables (dictionaries) // Written by Tim Budd // Oregon State University // June 1991 // // // copyrighted but can be freely redistributed as long as notice // of authorship is retained. # include "generictable.h" # include "genericlist.h" // ********************************************************* // Associations // ********************************************************* int genericAssociation::match(void * g) { return k == g; } // ********************************************************* // Association Lists // ********************************************************* class genericAssociationList : public genericList { public: ~genericAssociationList(); void remove(void *v) { genericList::remove(v); } protected: friend genericTable; genericList::includes; genericAssociation * current() { return (genericAssociation *) genericList::current(); } virtual int match(void *, void *); }; genericAssociationList::~genericAssociationList() { for (first(); current(); next()) delete current(); } int genericAssociationList::match(void * x, void * y) { genericAssociation * xp = (genericAssociation *) x; genericAssociation * yp = (genericAssociation *) y; return xp->match(yp); } // ********************************************************* // Tables // ********************************************************* genericTable::genericTable (int sz) : tablesize(sz) { elements = new genericAssociationList[tablesize]; } // genericTable::~genericTable() { delete [ tablesize ] elements; } // Edellisestä tulee käännettäessä ilmoitus: // "anachronistic use of array size in vector delete" // Niinpä laitamme tilalle: genericTable::~genericTable() { delete [] elements; } void genericTable::first() { for (index = 0; index < tablesize; index++) { elements[index].first(); if (elements[index].current()) return; } } void genericTable::next() { // continue the current list elements[index].next(); // or go on to the next if (! elements[index].current()) for (index++; index < tablesize; index++) { elements[index].first(); if (elements[index].current()) return; } } void * genericTable::current() { if ((index >= 0) && (index < tablesize)) if (elements[index].current()) return elements[index].current()->key(); return 0; } int genericTable::includesKey(void * e) { index = hash(e) % tablesize; return elements[index].includes(e); } genericAssociation * genericTable::makeAssociation(void * e) { return new genericAssociation(e); } void * & genericTable::operator [] (void * e) { genericAssociation * av; // first see if it is already there if (includesKey(e)) av = elements[index].current(); // if not, insert it else { av = makeAssociation(e); elements[index].addToFront(av); } return av->value(); } unsigned int genericTable::hash(void * e) { return (unsigned) this; } void genericTable::removeKey(void * e) { int i = hash(e) % tablesize; elements[i].remove(e); }