123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /**********************************************************************
- *<
- FILE: tab.h
- DESCRIPTION: Defines Tab Class
- CREATED BY: Dan Silva
- HISTORY: created 13 September 1994
- *> Copyright (c) 1994, All Rights Reserved.
- **********************************************************************/
- /*-------------------------------------------------------------------------------
- A Generic "Table" class.
-
- (DSilva 9-13-94)
- This is a type-safe variable length array which also supports list-like
- operations of insertion, appending and deleting. Two instance variables
- are maintained: "nalloc" is the number elements allocated in the
- array; "count" is the number actual used. (count<=nalloc).
- Allocation is performed automatically when Insert or Append operations
- are performed. It can also be done manually by calling Resize or Shrink.
- Note: Delete does not resize the storage: to do this call Shrink().
- If you are going to do a sequence of Appends, it's more efficient to
- first call Resize to make room for them. Beware of using the Addr
- function: it returns a pointer which may be invalid after subsequent
- Insert, Append, Delete, Resize, or Shrink operations.
-
-
- The implementation minimizes the storage of empty Tables: they are
- represented by a single NULL pointer. Also, the major part of the
- code is generic, shared by different Tabs for different types of elements.
- ------------------------------------------------------------------------------*/
- #ifndef __TAB__
- #define __TAB__
- #include <iostream.h>
- #include <malloc.h>
- typedef int CNT;
- typedef struct {
- CNT count;
- CNT nalloc;
- } TabHdr;
- ////////////////////////////////////////////////////////////////////////////////
- // Functions for internal use only: Clients should never call these.
- //
- UtilExport int TBMakeSize(TabHdr** pth, int num, int elsize);
- UtilExport int TBInsertAt(TabHdr** pth,int at, int num, void *el, int elsize, int extra);
- UtilExport int TBCopy(TabHdr** pth,int at, int num, void *el, int elsize);
- UtilExport int TBDelete(TabHdr** pth,int starting, int num, int elsize);
- UtilExport void TBSetCount(TabHdr** pth,int n, int elsize);
- UtilExport void zfree(void**p);
- ////////////////////////////////////////////////////////////////////////////////
- #define NoExport
-
- template <class T> class NoExport TabHd {
- public:
- CNT count;
- CNT nalloc;
- T data[100];
- TabHd() { count = 0; nalloc = 0; }
- };
- // Type of function to pass to Sort.
- // Note: Sort just uses the C lib qsort function. If we restricted
- // all Tab elements to have well defined <,>,== then we wouldn't need
- // this callback function.
- typedef int( __cdecl *CompareFnc) ( const void *elem1, const void *elem2 );
- template <class T> class NoExport Tab {
- private:
- TabHd<T> *th;
- /*
- struct TabHd {
- CNT count;
- CNT nalloc;
- T data[1];
- } *th;
- */
- public:
- Tab() { th = 0; }
- // Copy constructor
- Tab(const Tab& tb) {
- th = 0;
- TBCopy((TabHdr** )&th,0, tb.Count(), &tb.th->data, sizeof(T));
- }
- // Assignment operator
- Tab& operator=(const Tab& tb) {
- TBCopy((TabHdr** )&th,0, tb.Count(), &tb.th->data, sizeof(T));
- return *this;
- }
-
- ~Tab() { zfree((void**)&th); } // destructor
- int Count() const { return(th?th->count:0); } // return number of entries being used
- void ZeroCount() { if (th) th->count=0; }
- void SetCount(int n) { TBSetCount((TabHdr **)&th, n, sizeof(T)); }
- T& operator[](const int i) const { // access ith entry.
- assert(th&&(i<th->count)); return(th->data[i]);
- }
- T* Addr(const int i) const { // use with caution
- assert(th&&(i<th->count)); return(&th->data[i]);
- }
- // void *MemAddr() { return((void *)th); }
- // long MemSize() { return(th? (2*sizeof(CNT)+th->nalloc*sizeof(T)): 0);}
- // Insert "num" elements position "at"
- int Insert(int at, int num, T *el) {
- return(TBInsertAt((TabHdr**)&th, at, num, (void *)el, sizeof(T),0));
- }
- // Append "num" elements position on end of array"
- // If need to enlarge the array, allocate "allocExtra" extra slots
- int Append(int num, T *el, int allocExtra=0) {
- return(TBInsertAt((TabHdr**)&th,th?th->count:0,num, (void *)el,sizeof(T),allocExtra));
- }
- // List-type delete of "num" elements starting with "start"
- int Delete(int start,int num) {
- return(TBDelete((TabHdr**)&th,start,num,sizeof(T)));
- }
- // Change number of allocated items to num
- int Resize(int num) {
- return(TBMakeSize((TabHdr**)&th,num, sizeof(T)));
- }
- // Reallocate so there is no wasted space (nalloc = count)
- void Shrink() {
- TBMakeSize((TabHdr**)&th, th?th->count:0, sizeof(T));
- }
- void Sort(CompareFnc cmp) {
- if (th) {
- qsort(th->data,th->count,sizeof(T),cmp);
- }
- }
- #if 0
- void Print() {
- if (th==0) return;
- cout << "\nTable: count="<< th->count <<" nalloc="<< th->nalloc;
- cout << " elementSize= " << sizeof(T) << " Contents:\n";
- for (int i=0; i<th->count; i++)
- cout << " tab[" << i << "] = " << th->data[i] <<'\n';
- }
- #endif
- };
- #ifndef name2
- #define name2(a,b) a##b
- #endif
- #define MakeTab(TYPE) typedef Tab<TYPE> name2(TYPE,Tab);
- #endif
|