// cardtest.cc // // Example Use of the Generic Data Structures // Written by Tim Budd // Oregon State University // June 1991 // // copyrighted but can be freely redistributed as long as notice // of authorship is retained. # include # include "generictable.h" # include "genericlist.h" const int spade = 1; const int heart = 2; const int club = 3; const int diamond = 4; class Card { public: friend class CardList; friend class CardOrderedList; friend class CardStack; friend class CardQueue; friend class CardAssociation; friend class CardTable; Card(int r, int s); int rank(); int suit(); int color(); int operator == (Card & y); void print(); private: int r; int s; int refCount; }; inline Card::rank() { return r; } inline Card::suit() { return s; } inline Card::operator == (Card & y) { return (r == y.rank()) && (s == y.suit()); } void Card::print() { printf("suit %d rank %d\n", suit(), rank()); } inline Card::Card(int rv, int sv) { r = rv; s = sv; } inline int Card::color() { return suit() % 2; } // // test of lists // class CardList : public genericList { public: void add(Card * aCard) { genericList::addToEnd(aCard); } Card * current() { return (Card *) genericList::current(); } int includes(Card * aCard) { return genericList::includes(aCard); } void remove(Card * aCard) { genericList::remove(aCard); } void print(); protected: virtual int match(void *, void *); }; int CardList::match(void * x, void * y) { // we know x and y are really pointers to cards, // so first cast them Card * xp = (Card *) x; Card * yp = (Card *) y; return *xp == *yp; } void CardList::print() { for (first(); current(); next()) current()->print(); } void listTest() { CardList cl; Card * a = new Card(heart, 2); Card * b = new Card(diamond, 4); Card * c = new Card(club, 3); cl.add(a); cl.add(b); cl.add(c); cl.add(b); cl.print(); printf("includes test %d\n", cl.includes(new Card(diamond, 4))); // notice remove does not need pointer-same card cl.remove(new Card(club, 3)); cl.print(); } class CardIterator : public genericListIterator { public: CardIterator(CardList & cl) : genericListIterator(&cl) {} Card * current() { return (Card *) genericListIterator::current(); } }; void iteratorTest() { CardList cl; Card * a = new Card(heart, 2); Card * b = new Card(diamond, 4); Card * c = new Card(club, 3); cl.add(a); cl.add(b); cl.add(c); cl.add(b); CardIterator ci(cl); for (ci.first(); ci.current(); ci.next()) ci.current()->print(); } // // test of ordered lists // class IntegerHolder { public: int value; IntegerHolder(int i) {value = i; } }; class IntegerList : public genericOrderedList { public: void add(int); IntegerHolder * current() { return (IntegerHolder *) genericOrderedList::current(); } int currentValue(); int includes(int); void remove(int); ~IntegerList(); protected: virtual int compare(void *, void *); }; void IntegerList::add(int i) { genericOrderedList::add(new IntegerHolder(i)); } int IntegerList::currentValue() { IntegerHolder *p = current(); if (p) return p->value; return 0; } int IntegerList::includes(int i) { IntegerHolder *p = new IntegerHolder(i); int result = genericOrderedList::includes(p); delete p; return result; } void IntegerList::remove(int i) { IntegerHolder *p = new IntegerHolder(i); IntegerHolder *q = (IntegerHolder *) genericList::remove(p); if (q) delete q; delete p; } IntegerList::~IntegerList() { for (first(); current(); next()) delete current(); } int IntegerList::compare(void * x, void * y) { // we know x and y are really pointers to integer holders, // so first cast them IntegerHolder * xp = (IntegerHolder *) x; IntegerHolder * yp = (IntegerHolder *) y; if (xp->value == yp->value) return 0; else if (xp->value < yp->value) return -1; return 1; } int orderedTest() { IntegerList il; il.add(4); il.add(2); il.add(7); il.add(5); for (il.first(); il.current(); il.next()) printf("%d ", il.currentValue()); printf("\n"); printf("includes test %d\n", il.includes(7)); il.remove(5); for (il.first(); il.current(); il.next()) printf("%d ", il.currentValue()); printf("\n"); } // // test of sets // class CardSet : public genericSet { public: void add(Card * aCard) { genericSet::add(aCard); } Card * current() { return (Card *) genericSet::current(); } int includes(Card * aCard) { return 0 != genericSet::includes(aCard); } protected: virtual int match(void *, void *); }; int CardSet::match(void * x, void * y) { // we know x and y are really pointers to cards, // so first cast them Card * xp = (Card *) x; Card * yp = (Card *) y; return *xp == *yp; } void setTest() { Card * a = new Card(1, 1); Card * b = new Card(2, 2); Card * c = new Card(3, 3); CardSet cs; cs.add(a); cs.add(b); cs.add(b); cs.add(c); for (cs.first(); cs.current(); cs.next()) cs.current()->print(); } // // test of stacks/queues lists // class CardStack : public genericStack { public: void push(Card * aCard); void pop(); Card * current() { return (Card *) genericStack::current(); } Card * top() { return (Card *) genericStack::top(); } ~CardStack(); }; void CardStack::push(Card * aCard) { genericStack::push(aCard); aCard->refCount++; } void CardStack::pop() { Card * p = top(); if (p) { genericStack::pop(); if (--(p->refCount) == 0) delete p; } } CardStack::~CardStack() { for (first(); current(); next()) if (--(current()->refCount) == 0) delete current(); } int stackTest() { CardStack cl; Card * a = new Card(heart, 2); Card * b = new Card(diamond, 4); Card * c = new Card(club, 3); cl.push(a); cl.push(b); cl.push(c); cl.push(b); for (cl.first(); cl.current(); cl.next()) cl.current()->print(); cl.top()->print(); cl.pop(); for (cl.first(); cl.current(); cl.next()) cl.current()->print(); } class CardQueue : public genericQueue { public: void push(Card * aCard); Card * current() { return (Card *) genericQueue::current(); } Card * top() { return (Card *) genericQueue::top(); } void pop(); // // the following are new methods added just for lists of // cards ~CardQueue(); void print(); }; void CardQueue::push(Card * aCard) { genericQueue::push(aCard); aCard->refCount++; } void CardQueue::pop() { Card * c = top(); if (c) { genericQueue::pop(); if (--(c->refCount) == 0) delete c; } } CardQueue::~CardQueue() { for (first(); current(); next()) if (--(current()->refCount) == 0) delete current(); } void CardQueue::print() { printf("the pack is:\n"); for (first(); current(); next()) current()->print(); printf("end of pack\n"); } int queueTest() { CardQueue cl; Card * a = new Card(heart, 2); Card * b = new Card(diamond, 4); Card * c = new Card(club, 3); cl.push(a); cl.push(b); cl.push(c); cl.push(b); cl.print(); cl.top()->print(); cl.pop(); cl.print(); } // // table test // class CardAssociation : public genericAssociation { public: CardAssociation ( Card * e ) : genericAssociation(e) {} Card * key() { return (Card *) genericAssociation::key(); } Card *& value() { return (Card*&) genericAssociation::value(); } protected: virtual int match (void *); }; int CardAssociation::match(void * y) { Card * yp = (Card *) y; return (key()->rank() == yp->rank()) && (key()->suit() == yp->suit()); } class CardTable : public genericTable { protected: virtual unsigned int hash(void *); //virtual genericAssociation * makeAssociation(void *); public: Card * & operator [] (Card * x) { return (Card * &) genericTable::operator[](x); } Card * current() { return (Card *) genericTable::current(); } int includesKey(Card * x) { return genericTable::includesKey(x); } void removeKey(Card * x) { genericTable::removeKey(x); } }; unsigned int CardTable::hash(void * x) { Card * xp = (Card *) x; return xp->rank(); } # if 0 genericAssociation * CardTable::makeAssociation(void * e) { return new CardAssociation((Card *) e); } # endif void tabletest() { CardTable ct; Card * one = new Card(1, 1); Card * two = new Card(2, 2); Card * three = new Card(3, 3); Card * four = new Card(4, 4); Card * five = new Card(5, 5); ct[one] = two; ct[two] = three; ct[three] = four; ct[four] = five; printf("print first card\n"); ct[two]->print(); printf("now print list\n"); for (ct.first(); ct.current(); ct.next()) { Card * p = ct.current(); printf("here's a key/value pair\n"); p->print(); ct[p]->print(); } printf("removal test\n"); ct.removeKey(three); for (ct.first(); ct.current(); ct.next()) { Card * p = ct.current(); printf("here's a key/value pair\n"); p->print(); ct[p]->print(); } } main() { orderedTest(); listTest(); iteratorTest(); /* int orderedTest(); */ setTest(); /* int */ stackTest(); /* int */ queueTest(); }