1 | /**********************************************************************
|
---|
2 | *<
|
---|
3 | FILE: tab.h
|
---|
4 |
|
---|
5 | DESCRIPTION: Defines Tab Class
|
---|
6 |
|
---|
7 | CREATED BY: Dan Silva
|
---|
8 |
|
---|
9 | HISTORY: created 13 September 1994
|
---|
10 |
|
---|
11 | *> Copyright (c) 1994, All Rights Reserved.
|
---|
12 | **********************************************************************/
|
---|
13 |
|
---|
14 | /*-------------------------------------------------------------------------------
|
---|
15 |
|
---|
16 | A Generic "Table" class.
|
---|
17 |
|
---|
18 | (DSilva 9-13-94)
|
---|
19 |
|
---|
20 | This is a type-safe variable length array which also supports list-like
|
---|
21 | operations of insertion, appending and deleting. Two instance variables
|
---|
22 | are maintained: "nalloc" is the number elements allocated in the
|
---|
23 | array; "count" is the number actual used. (count<=nalloc).
|
---|
24 | Allocation is performed automatically when Insert or Append operations
|
---|
25 | are performed. It can also be done manually by calling Resize or Shrink.
|
---|
26 | Note: Delete does not resize the storage: to do this call Shrink().
|
---|
27 | If you are going to do a sequence of Appends, it's more efficient to
|
---|
28 | first call Resize to make room for them. Beware of using the Addr
|
---|
29 | function: it returns a pointer which may be invalid after subsequent
|
---|
30 | Insert, Append, Delete, Resize, or Shrink operations.
|
---|
31 |
|
---|
32 |
|
---|
33 | The implementation minimizes the storage of empty Tables: they are
|
---|
34 | represented by a single NULL pointer. Also, the major part of the
|
---|
35 | code is generic, shared by different Tabs for different types of elements.
|
---|
36 |
|
---|
37 | ------------------------------------------------------------------------------*/
|
---|
38 |
|
---|
39 | #ifndef __TAB__
|
---|
40 |
|
---|
41 | #define __TAB__
|
---|
42 |
|
---|
43 | #include <iostream.h>
|
---|
44 | #include <malloc.h>
|
---|
45 |
|
---|
46 | typedef int CNT;
|
---|
47 |
|
---|
48 | typedef struct {
|
---|
49 | CNT count;
|
---|
50 | CNT nalloc;
|
---|
51 | } TabHdr;
|
---|
52 |
|
---|
53 | ////////////////////////////////////////////////////////////////////////////////
|
---|
54 | // Functions for internal use only: Clients should never call these.
|
---|
55 | //
|
---|
56 | UtilExport int TBMakeSize(TabHdr** pth, int num, int elsize);
|
---|
57 | UtilExport int TBInsertAt(TabHdr** pth,int at, int num, void *el, int elsize, int extra);
|
---|
58 | UtilExport int TBCopy(TabHdr** pth,int at, int num, void *el, int elsize);
|
---|
59 | UtilExport int TBDelete(TabHdr** pth,int starting, int num, int elsize);
|
---|
60 | UtilExport void TBSetCount(TabHdr** pth,int n, int elsize);
|
---|
61 | UtilExport void zfree(void**p);
|
---|
62 | ////////////////////////////////////////////////////////////////////////////////
|
---|
63 |
|
---|
64 | #define NoExport
|
---|
65 |
|
---|
66 | template <class T> class NoExport TabHd {
|
---|
67 | public:
|
---|
68 | CNT count;
|
---|
69 | CNT nalloc;
|
---|
70 | T data[100];
|
---|
71 | TabHd() { count = 0; nalloc = 0; }
|
---|
72 | };
|
---|
73 |
|
---|
74 |
|
---|
75 | // Type of function to pass to Sort.
|
---|
76 | // Note: Sort just uses the C lib qsort function. If we restricted
|
---|
77 | // all Tab elements to have well defined <,>,== then we wouldn't need
|
---|
78 | // this callback function.
|
---|
79 | typedef int( __cdecl *CompareFnc) ( const void *elem1, const void *elem2 );
|
---|
80 |
|
---|
81 |
|
---|
82 |
|
---|
83 | template <class T> class NoExport Tab {
|
---|
84 | private:
|
---|
85 | TabHd<T> *th;
|
---|
86 | /*
|
---|
87 | struct TabHd {
|
---|
88 | CNT count;
|
---|
89 | CNT nalloc;
|
---|
90 | T data[1];
|
---|
91 | } *th;
|
---|
92 | */
|
---|
93 | public:
|
---|
94 | Tab() { th = 0; }
|
---|
95 | // Copy constructor
|
---|
96 | Tab(const Tab& tb) {
|
---|
97 | th = 0;
|
---|
98 | TBCopy((TabHdr** )&th,0, tb.Count(), &tb.th->data, sizeof(T));
|
---|
99 | }
|
---|
100 | // Assignment operator
|
---|
101 | Tab& operator=(const Tab& tb) {
|
---|
102 | TBCopy((TabHdr** )&th,0, tb.Count(), &tb.th->data, sizeof(T));
|
---|
103 | return *this;
|
---|
104 | }
|
---|
105 |
|
---|
106 | ~Tab() { zfree((void**)&th); } // destructor
|
---|
107 |
|
---|
108 | int Count() const { return(th?th->count:0); } // return number of entries being used
|
---|
109 |
|
---|
110 | void ZeroCount() { if (th) th->count=0; }
|
---|
111 | void SetCount(int n) { TBSetCount((TabHdr **)&th, n, sizeof(T)); }
|
---|
112 |
|
---|
113 | T& operator[](const int i) const { // access ith entry.
|
---|
114 | assert(th&&(i<th->count)); return(th->data[i]);
|
---|
115 | }
|
---|
116 | T* Addr(const int i) const { // use with caution
|
---|
117 | assert(th&&(i<th->count)); return(&th->data[i]);
|
---|
118 | }
|
---|
119 | // void *MemAddr() { return((void *)th); }
|
---|
120 | // long MemSize() { return(th? (2*sizeof(CNT)+th->nalloc*sizeof(T)): 0);}
|
---|
121 |
|
---|
122 | // Insert "num" elements position "at"
|
---|
123 | int Insert(int at, int num, T *el) {
|
---|
124 | return(TBInsertAt((TabHdr**)&th, at, num, (void *)el, sizeof(T),0));
|
---|
125 | }
|
---|
126 | // Append "num" elements position on end of array"
|
---|
127 | // If need to enlarge the array, allocate "allocExtra" extra slots
|
---|
128 | int Append(int num, T *el, int allocExtra=0) {
|
---|
129 | return(TBInsertAt((TabHdr**)&th,th?th->count:0,num, (void *)el,sizeof(T),allocExtra));
|
---|
130 | }
|
---|
131 | // List-type delete of "num" elements starting with "start"
|
---|
132 | int Delete(int start,int num) {
|
---|
133 | return(TBDelete((TabHdr**)&th,start,num,sizeof(T)));
|
---|
134 | }
|
---|
135 | // Change number of allocated items to num
|
---|
136 | int Resize(int num) {
|
---|
137 | return(TBMakeSize((TabHdr**)&th,num, sizeof(T)));
|
---|
138 | }
|
---|
139 | // Reallocate so there is no wasted space (nalloc = count)
|
---|
140 | void Shrink() {
|
---|
141 | TBMakeSize((TabHdr**)&th, th?th->count:0, sizeof(T));
|
---|
142 | }
|
---|
143 |
|
---|
144 | void Sort(CompareFnc cmp) {
|
---|
145 | if (th) {
|
---|
146 | qsort(th->data,th->count,sizeof(T),cmp);
|
---|
147 | }
|
---|
148 | }
|
---|
149 |
|
---|
150 | #if 0
|
---|
151 | void Print() {
|
---|
152 | if (th==0) return;
|
---|
153 | cout << "\nTable: count="<< th->count <<" nalloc="<< th->nalloc;
|
---|
154 | cout << " elementSize= " << sizeof(T) << " Contents:\n";
|
---|
155 | for (int i=0; i<th->count; i++)
|
---|
156 | cout << " tab[" << i << "] = " << th->data[i] <<'\n';
|
---|
157 | }
|
---|
158 | #endif
|
---|
159 | };
|
---|
160 |
|
---|
161 | #ifndef name2
|
---|
162 | #define name2(a,b) a##b
|
---|
163 | #endif
|
---|
164 |
|
---|
165 | #define MakeTab(TYPE) typedef Tab<TYPE> name2(TYPE,Tab);
|
---|
166 |
|
---|
167 | #endif
|
---|