tab.h 5.4 KB

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