00001
00002
00003
00004
00005 #ifndef _GARRAY_H_
00006 #define _GARRAY_H_
00007
00008 #include <stdlib.h>
00009 #include <assert.h>
00010 #include "LgiDefs.h"
00011 #include "GMem.h"
00012
00013 #define GARRAY_MIN_SIZE 16
00014
00031 template <class Type>
00032 class GArray
00033 {
00034 Type *p;
00035 uint32 len;
00036 uint32 alloc;
00037
00038 protected:
00039 bool fixed;
00040
00041 public:
00043 GArray(int PreAlloc = 0)
00044 {
00045 p = 0;
00046 len = 0;
00047 fixed = false;
00048
00049 alloc = PreAlloc;
00050 if (alloc)
00051 {
00052 int Bytes = sizeof(Type) * alloc;
00053 p = (Type*) malloc(Bytes);
00054 if (p)
00055 {
00056 memset(p, 0, Bytes);
00057 }
00058 else
00059 {
00060 alloc = 0;
00061 }
00062 }
00063 }
00064
00065 GArray(const GArray<Type> &c)
00066 {
00067 p = 0;
00068 alloc = len = 0;
00069 fixed = false;
00070 *this = c;
00071 }
00072
00074 ~GArray()
00075 {
00076 Length(0);
00077 }
00078
00080 uint32 Length() const
00081 {
00082 return len;
00083 }
00084
00086 bool Length(uint32 i)
00087 {
00088 if (i > 0)
00089 {
00090 if (i > len && fixed)
00091 return false;
00092
00093 uint nalloc = alloc;
00094 if (i < len)
00095 {
00096
00097 }
00098 else
00099 {
00100
00101 int b;
00102 for (b = 4; (1 << b) < i; b++)
00103 ;
00104 nalloc = 1 << b;
00105 LgiAssert(nalloc >= i);
00106 }
00107
00108 if (nalloc != alloc)
00109 {
00110 Type *np = (Type*)malloc(sizeof(Type) * nalloc);
00111 if (!np)
00112 {
00113 return false;
00114 }
00115
00116 if (p)
00117 {
00118
00119 memcpy(np, p, min(len, i) * sizeof(Type));
00120 free(p);
00121 }
00122 p = np;
00123 alloc = nalloc;
00124 }
00125
00126 if (i > len)
00127 {
00128
00129 memset(p + len, 0, sizeof(Type) * (nalloc - len));
00130 }
00131
00132 len = i;
00133 }
00134 else
00135 {
00136 if (p)
00137 {
00138 int Length = len;
00139 for (uint i=0; i<Length; i++)
00140 {
00141 p[i].~Type();
00142 }
00143 free(p);
00144 p = 0;
00145 }
00146 len = alloc = 0;
00147 }
00148
00149 return true;
00150 }
00151
00152 GArray<Type> &operator =(const GArray<Type> &a)
00153 {
00154 Length(a.Length());
00155 if (p && a.p)
00156 {
00157 for (int i=0; i<len; i++)
00158 {
00159 p[i] = a.p[i];
00160 }
00161 }
00162 return *this;
00163 }
00164
00169 Type &operator [](uint32 i)
00170 {
00171 static Type t;
00172 if
00173 (
00174 i < 0
00175 ||
00176 (fixed && i >= len)
00177 )
00178 {
00179 ZeroObj(t);
00180 return t;
00181 }
00182
00183 #if 1
00184 if (i > 64<<20)
00185 {
00186 #if defined(_DEBUG) && defined(_MSC_VER)
00187 LgiAssert(0);
00188 #endif
00189
00190 ZeroObj(t);
00191 return t;
00192 }
00193 #endif
00194
00195 if (i >= alloc)
00196 {
00197
00198 uint nalloc = max(alloc, GARRAY_MIN_SIZE);
00199 while (nalloc <= i)
00200 {
00201 nalloc <<= 1;
00202 }
00203
00204
00205 Type *np = (Type*) malloc(sizeof(Type) * nalloc);
00206 if (np)
00207 {
00208
00209 memset(np + len, 0, (nalloc - len) * sizeof(Type));
00210 if (p)
00211 {
00212
00213 memcpy(np, p, len * sizeof(Type));
00214
00215
00216 free(p);
00217 }
00218
00219
00220 p = np;
00221 alloc = nalloc;
00222 }
00223 else
00224 {
00225 static Type *t = 0;
00226 return *t;
00227 }
00228 }
00229
00230
00231 if (i + 1 > len)
00232 {
00233 len = i + 1;
00234 }
00235
00236 return p[i];
00237 }
00238
00240 void DeleteObjects()
00241 {
00242 for (uint i=0; i<len; i++)
00243 {
00244 DeleteObj(p[i]);
00245 }
00246 Length(0);
00247 }
00248
00250 void DeleteArrays()
00251 {
00252 for (int i=0; i<len; i++)
00253 {
00254 DeleteArray(p[i]);
00255 }
00256 Length(0);
00257 }
00258
00260 int IndexOf(Type n)
00261 {
00262 for (uint i=0; i<len; i++)
00263 {
00264 if (p[i] == n) return i;
00265 }
00266
00267 return -1;
00268 }
00269
00271 bool HasItem(Type n)
00272 {
00273 return IndexOf(n) >= 0;
00274 }
00275
00277 bool DeleteAt
00278 (
00280 uint Index,
00282 bool Ordered = false
00283 )
00284 {
00285 if (p && Index >= 0 && Index < len)
00286 {
00287
00288 p[Index].~Type();
00289
00290
00291 if (Index < len - 1)
00292 {
00293 if (Ordered)
00294 {
00295 memmove(p + Index, p + Index + 1, (len - Index - 1) * sizeof(Type) );
00296 }
00297 else
00298 {
00299 p[Index] = p[len-1];
00300 }
00301 }
00302
00303
00304 len--;
00305
00306
00307 memset(p + len, 0, sizeof(Type));
00308 return true;
00309 }
00310
00311 return false;
00312 }
00313
00315 bool Delete
00316 (
00318 Type n,
00320 bool Ordered = false
00321 )
00322 {
00323 int i = IndexOf(n);
00324 if (p && i >= 0)
00325 {
00326 return DeleteAt(i, Ordered);
00327 }
00328
00329 return false;
00330 }
00331
00333 void Add
00334 (
00336 const Type &n
00337 )
00338 {
00339 (*this)[len] = n;
00340 }
00341
00343 void Add
00344 (
00346 Type *s,
00348 int count
00349
00350 )
00351 {
00352 if (!s || count < 1)
00353 return;
00354
00355 int i = len;
00356 Length(len + count);
00357 Type *d = p + i;
00358 while (count--)
00359 {
00360 *d++ = *s++;
00361 }
00362 }
00363
00365 void Add
00366 (
00368 GArray<Type> &a
00369
00370 )
00371 {
00372 int old = len;
00373 if (Length(len + a.Length()))
00374 {
00375 for (int i=0; i<a.Length(); i++, old++)
00376 p[old] = a[i];
00377 }
00378 }
00379 GArray<Type> &operator +(GArray<Type> &a)
00380 {
00381 Add(a);
00382 return *this;
00383 }
00384
00386 bool AddAt
00387 (
00389 int Index,
00391 Type n
00392 )
00393 {
00394
00395 if (Length(len + 1))
00396 {
00397 if (Index < len - 1)
00398 {
00399
00400 memmove(p + Index + 1, p + Index, (len - Index - 1) * sizeof(Type) );
00401 }
00402 else if (Index >= len)
00403 {
00404
00405 Index = len - 1;
00406 }
00407
00408
00409 p[Index] = n;
00410
00411 return true;
00412 }
00413
00414 return false;
00415 }
00416
00418 void Sort(int (*Compare)(Type*, Type*))
00419 {
00420 typedef int (*qsort_compare)(const void *, const void *);
00421 qsort(p, len, sizeof(Type), (qsort_compare)Compare);
00422 }
00423
00425 Type &New()
00426 {
00427 return (*this)[len];
00428 }
00429
00431 Type *Release()
00432 {
00433 Type *Ptr = p;
00434 p = 0;
00435 len = alloc = 0;
00436 return Ptr;
00437 }
00438
00439 template <class T>
00440 class Iter
00441 {
00442 int i;
00443 int8 each_dir;
00444 GArray<T> *a;
00445
00446 public:
00447 Iter(GArray<T> *arr, int pos)
00448 {
00449 i = pos;
00450 a = arr;
00451 each_dir = 0;
00452 }
00453
00454 bool Each()
00455 {
00456 if (each_dir) i += each_dir;
00457 else each_dir = i == 0 ? 1 : -1;
00458 return In();
00459 }
00460
00461 operator bool() { return In(); }
00462 bool In() { return i >= 0 && i < a->Length(); }
00463 bool End() { return i < 0 || i >= a->Length(); }
00464 T &operator *() { return (*a)[i]; }
00465 Iter<T> &operator ++() { i++; return *this; }
00466 Iter<T> &operator --() { i--; return *this; }
00467 Iter<T> &operator ++(int) { i++; return *this; }
00468 Iter<T> &operator --(int) { i--; return *this; }
00469 };
00470
00471 typedef Iter<Type> I;
00472 I Start() { return I(this, 0); }
00473 I End() { return I(this, Length()-1); }
00474 };
00475
00476 #endif