// Copyright (c) 1999 Philip A. Hardin (pahardin@cs.utexas.edu) // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License v2 or later. #ifndef TABLE_h #define TABLE_h #include // to get NULL #include "general.h" /************************************************************************/ template struct table { int num; // number of objects which are in table double growth; // factor by which to expand table size when // an obj is added to a full table private: c *objs; // dynamically allocated table of objects int size; // max num of objects which can fit in table public: table(int initialSize=32,double grow=1.5); table(const table& t) {Copy(t);}; // copy constructor ~table() {if (objs!=NULL) delete [] objs;}; table& operator=(const table& t) {FreeArray(); Copy(t); return *this;}; int Add(const c&); c& operator[](int i) const {return objs[i];}; int Num() const {return num;}; c *Array() const {return objs;}; void Empty(int newSize=32) {FreeArray(); AllocArray(newSize);}; int AddIfAbsent(const c&,bool& wasAbsent); int Find(const c&); private: void Copy(const table&); void AllocArray(int newSize); void FreeArray() {if (objs!=NULL) delete [] objs;}; }; /*----------------------------------------------------------------------*/ // Attempts to allocate the array of objects, and sets num & size accordingly // If the array is already allocated, doesn't free the old one template inline void table::AllocArray (int newSize) { objs= new c[newSize]; num= 0; size= newSize; } /*----------------------------------------------------------------------*/ template table::table (int initialSize, double grow) { growth= grow; AllocArray(initialSize); } /*----------------------------------------------------------------------*/ // IMPORTANT: Assumes that this table's array is not already allocated template void table::Copy (const table& t) { growth= t.growth; AllocArray(t.size); if (objs != NULL) { num= t.num; forii(num) objs[i]= t[i]; } } /*----------------------------------------------------------------------*/ // Returns the index of the object added template int table::Add(const c& obj) { if (num==size) { // if table is full int newSize= (int) (size*growth +0.5); // compute size of new, larger table c *newObjs= new c[newSize]; // allocate new table forii(size) // copy old table to new table newObjs[i]= objs[i]; delete [] objs; // delete old table objs= newObjs; size= newSize; } objs[num++]= obj; return num-1; } /*----------------------------------------------------------------------*/ // Returns the index of the object, if it was found in the table, or -1 if // the object wasn't found in the table template int table::Find(const c& obj) { forii(num) if (objs[i] == obj) return i; return -1; } /*----------------------------------------------------------------------*/ // Adds the object to the table if it is not already present. // Returns the index of the object in the table. template int table::AddIfAbsent(const c& obj,bool& wasAbsent) { int idx= Find(obj); wasAbsent= (idx <0); if (wasAbsent) return Add(obj); else return idx; } #endif