00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __CS_GARRAY_H__
00021 #define __CS_GARRAY_H__
00022
00034 template <class T>
00035 class csGrowingArray
00036 {
00037 private:
00038 int count, limit, threshold;
00039 int shrinklimit;
00040 T* root;
00041 int RefCount;
00042
00043 public:
00048 csGrowingArray (int ilimit = 0, int ithreshold = 0, int ishrinklimit = 0)
00049 {
00050 RefCount = 0;
00051 count = 0;
00052 limit = (ilimit > 0 ? ilimit : 0);
00053 threshold = (ithreshold > 0 ? ithreshold : 16);
00054 shrinklimit = (ishrinklimit > 0 ? ishrinklimit : 1000);
00055 if (limit != 0)
00056 root = (T*)malloc (limit * sizeof(T));
00057 else
00058 root = NULL;
00059 }
00060
00064 void DeleteAll ()
00065 {
00066 if (root)
00067 {
00068 free (root);
00069 root = NULL;
00070 count = 0;
00071 limit = 0;
00072 }
00073 }
00074
00078 ~csGrowingArray ()
00079 {
00080 DeleteAll ();
00081 }
00082
00083
00084 void IncRef () { RefCount++; }
00085
00086
00087 void DecRef ()
00088 {
00089 if (RefCount == 1) { SetLimit (0); count = 0; }
00090 RefCount--;
00091 }
00092
00094 void SetLimit (int inlimit)
00095 {
00096 if (limit == inlimit) return;
00097 if ((limit = inlimit) != 0)
00098 root = (T*)realloc (root, limit * sizeof (T));
00099 else if (root) { free (root); root = NULL; }
00100 if (count > limit) count = limit;
00101 }
00102
00104 void SetLength (int n)
00105 {
00106 count = n;
00107 int newlimit = ((count + (threshold - 1)) / threshold) * threshold;
00108 if (newlimit > limit || newlimit < limit-shrinklimit)
00109 SetLimit (newlimit);
00110 }
00111
00113 int Length () const
00114 {
00115 return count;
00116 }
00117
00119 int Limit () const
00120 {
00121 return limit;
00122 }
00123
00125 T* GetArray ()
00126 {
00127 return root;
00128 }
00129
00131 const T* GetArray () const
00132 {
00133 return root;
00134 }
00135
00137 const T& Get (int n) const
00138 {
00139 CS_ASSERT (n >= 0 && n < count);
00140 return root[n];
00141 }
00142
00144 const T& operator [] (int n) const
00145 {
00146 CS_ASSERT (n >= 0 && n < count);
00147 return root[n];
00148 }
00149
00151 T& operator [] (int n)
00152 {
00153 CS_ASSERT (n >= 0);
00154 if (n >= count)
00155 SetLength (n + 1);
00156 return root[n];
00157 }
00158
00160 int Push (const T& what)
00161 {
00162 SetLength (count + 1);
00163 root [count - 1] = what;
00164 return (count - 1);
00165 }
00166
00168 int PushSmart (const T& what)
00169 {
00170 int n = Find (what);
00171 return (n == -1) ? Push (what) : n;
00172 }
00173
00175 T Pop ()
00176 {
00177 T ret = root [count - 1];
00178 SetLength (count - 1);
00179 return ret;
00180 }
00181
00183 T& Top () const
00184 {
00185 return root [count - 1];
00186 }
00187
00189 bool Delete (int n)
00190 {
00191 if (n >= 0 && n < count)
00192 {
00193 const int ncount = count - 1;
00194 const int nmove = ncount - n;
00195 if (nmove > 0)
00196 {
00197 memmove (&root [n], &root [n + 1], nmove * sizeof (T));
00198 }
00199 SetLength (ncount);
00200 return true;
00201 }
00202 else
00203 return false;
00204 }
00205
00207 bool Insert (int n, const T& item)
00208 {
00209 if (n <= count)
00210 {
00211 SetLength (count + 1);
00212 const int nmove = (count - n - 1);
00213 if (nmove > 0)
00214 {
00215 memmove (&root [n + 1], &root [n], nmove * sizeof (T));
00216 }
00217 root [n] = item;
00218 return true;
00219 }
00220 else
00221 return false;
00222 }
00223 };
00224
00225
00226 #endif // __CS_GARRAY_H__