initial
[prop.git] / include / AD / contain / vararray.h
blobd0dc45a7c84b039bee34ada1deae87f010fe9bd3
1 //////////////////////////////////////////////////////////////////////////////
2 // NOTICE:
3 //
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
9 // your programs.
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
16 // code.
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
21 // Allen Leung
22 // 1994
23 //////////////////////////////////////////////////////////////////////////////
25 #ifndef variable_sized_array_h
26 #define variable_sized_array_h
28 ///////////////////////////////////////////////////////////////////////////
29 // Class VarArray<T> provides an abstraction for
30 // an dense mapping from integers to type T.
31 // The array will grow in size when necessary.
32 // Both positive and negative indices are allowed.
33 // The indices should be centered around 0.
34 ///////////////////////////////////////////////////////////////////////////
36 #include <new.h>
37 #include <string.h>
38 #include <AD/generic/generic.h> // Generic definitions
40 template<class T>
41 class VarArray {
42 T * array; // array of elements; displaced by offset
43 int low, high; // upper and lower bound on array
44 int growthRate; // minimal number of elements for expansion
46 void grow(int i);
48 public:
50 //////////////////////////////////////////////////////////////////
51 // Constructor and destructors
52 //////////////////////////////////////////////////////////////////
53 VarArray(int lowerBound = 0,
54 int upperBound = 9, int growthFactor = 32);
55 VarArray(const VarArray& A) : array(0), low(0) { *this = A; }
56 VarArray(size_t size, const T []);
57 ~VarArray();
59 ////////////////////////////////////////////////////////////////////
60 // Assignment
61 ////////////////////////////////////////////////////////////////////
62 VarArray& operator = (const VarArray&);
64 ////////////////////////////////////////////////////////////////////
65 // Conversion
66 ////////////////////////////////////////////////////////////////////
67 inline operator const T * () const { return array; }
68 inline operator T * () { return array; }
70 ////////////////////////////////////////////////////////////////////
71 // Selectors
72 ////////////////////////////////////////////////////////////////////
73 inline int hi() const { return high; }
74 inline int lo() const { return low; }
75 inline int size() const { return high - low + 1; }
76 inline int capacity() const { return size(); }
77 inline Bool hasKey(int i) const { return i >= low && i <= high; }
78 inline const T& operator [] (int i) const { return array[i]; }
79 inline T& operator [] (int i)
80 { if (! hasKey(i)) grow(i); return array[i]; }
82 ////////////////////////////////////////////////////////////////////
83 // Iteration
84 ////////////////////////////////////////////////////////////////////
85 inline Ix first() const { return low > high ? 0 : (Ix)&array[lo()]; }
86 inline Ix last() const { return low > high ? 0 : (Ix)&array[hi()]; }
87 inline Ix next(Ix i) const { return i >= (Ix)(array + hi()) ? 0 : (((T*)i)+1); }
88 inline Ix prev(Ix i) const { return i <= (Ix)(array + lo()) ? 0 : (((T*)i)-1); }
89 inline const T& operator() (Ix i) const { return *(T*)i; }
90 inline T& operator() (Ix i) { return *(T*)i; }
93 ////////////////////////////////////////////////////////////////////
94 // Implementation comes here
95 ////////////////////////////////////////////////////////////////////
96 template<class T>
97 VarArray<T>::VarArray(int lowerBound, int upperBound, int growthFactor)
98 { long size = lowerBound <= upperBound ? upperBound - lowerBound + 1 : 0;
99 high = upperBound; low = lowerBound;
100 T * mem = size > 0 ? new T [size] : (T*)0;
101 array = mem - low;
102 growthRate = growthFactor;
105 template<class T>
106 VarArray<T>::VarArray(size_t size, const T A[])
107 { array = new T [size];
108 low = 0; high = size - 1;
109 growthRate = 32;
110 for (register int i = high; i >= 0; i--) array[i] = A[i];
113 template<class T>
114 VarArray<T>::~VarArray()
115 { delete [] (array + low); }
117 template<class T>
118 VarArray<T>& VarArray<T>::operator = (const VarArray<T>& A)
119 { if (this != &A) {
120 delete [] (array + low);
121 high = A.high; low = A.low;
122 array = new T [high - low + 1] - A.low;
123 for (int i = low; i <= high; i++) array[i] = A.array[i];
125 return *this;
128 template<class T>
129 void VarArray<T>::grow(int i)
130 { int newHigh, newLow;
131 int growth = growthRate <= 0 ? (size() * 3 / 2 + 32) : growthRate;
132 if (i > high)
133 if (i < high + growth) newHigh = high + growth;
134 else newHigh = i;
135 else newHigh = high;
136 if (i < low)
137 if (i > low - growth) newLow = low - growth;
138 else newLow = i;
139 else newLow = low;
140 register T * newArray = new T [newHigh - newLow + 1] - newLow;
141 for (register int j = low; j <= high; j++) newArray[j] = array[j];
142 delete [] (array + low);
143 array = newArray;
144 low = newLow; high = newHigh;
147 #endif