00001
00002
00003
00004
00005
00006
00007
00008 template <class DATA>
00009 class Array : virtual public SystemCode {
00010 _PROTECTED_:
00011
00012 DATA* Data;
00013 uint32 G;
00014
00015 uint32 A;
00016 void _qsort_asc(DATA* b, int left, int right);
00017 void _qsort_dec(DATA* b, int left, int right);
00018 public:
00019 uint32 flgs;
00020
00021 void ctor();
00022 Array() {ctor();}
00023 Array(uint32 size);
00024
00025 ~Array() {
00026 if (Data) MemFree(Data);
00027 }
00028
00029 uint32 Count;
00030 uint32 Offset;
00031 BOOL Eol;
00032
00033 void ReAlloc(uint32 size);
00034 DATA &Insert(DATA x, BOOL _inc = TRUE);
00035 DATA &Insert(DATA *x, BOOL _inc = TRUE) { return Insert(*x, _inc); }
00036 DATA &Insert();
00037 BOOL Delete();
00038 BOOL Set(DATA x, BOOL _inc = TRUE);
00039 BOOL Set(DATA *x, BOOL _inc = TRUE) { return Set(*x, _inc); }
00040 BOOL Get(DATA &x, BOOL _inc = TRUE);
00041 BOOL Get(DATA *&x, BOOL _inc = TRUE);
00042 int Find(DATA x);
00043 int Find(DATA *x) { return Find(*x);}
00044 void Sort(BOOL asc = TRUE);
00045
00046 BOOL Seek(int32 Offset, int fromwhere);
00047
00048 DATA &operator [](int);
00049 DATA &operator =(DATA);
00050
00051 void SetGranularity(uint32 size);
00052 };
00053
00054 template <class DATA>
00055 DATA &Array<DATA>::operator [](int idx) {
00056 if (idx >= Count) SystemCode::RaiseException(ERR_ASSERT);
00057 return Data[idx];
00058 }
00059
00060 template <class DATA>
00061 DATA &Array<DATA>::operator =(DATA x) {
00062 if (Eol) SystemCode::RaiseException(ERR_ASSERT);
00063 Set(x, FALSE);
00064 return Data[Offset];
00065 }
00066
00067 template <class DATA>
00068 void Array<DATA>::ctor() {
00069 Eol = TRUE;
00070 Offset = 0;
00071 Count = 0;
00072 G = 1;
00073 Data = (DATA*)NULL;
00074 }
00075
00076 template <class DATA>
00077 Array<DATA>::Array(uint32 size) {
00078 ctor();
00079 if (!size) return;
00080 Count = size;
00081 Eol = FALSE;
00082 Data = (DATA*) SystemCode::MemAlloc(size * sizeof(DATA));
00083 }
00084
00085
00086 template <class DATA>
00087 DATA &Array<DATA>::Insert(DATA x, BOOL _inc) {
00088 int retOffset = Offset;
00089 Count++;
00090 ReAlloc(Count);
00091 if (Eol) {
00092
00093 Eol = FALSE;
00094 } else {
00095
00096 memcpy(Data + (Offset + 1), Data + Offset, (Count - 1 - Offset) * sizeof(DATA));
00097 }
00098 Data[Offset] = x;
00099 if (_inc) {
00100 Offset++;
00101 if (Offset == Count) Eol = TRUE;
00102 }
00103 return Data[retOffset];
00104 }
00105
00106
00107 template <class DATA>
00108 DATA &Array<DATA>::Insert() {
00109 uint32 retOffset = Offset;
00110 Count++;
00111 ReAlloc(Count);
00112 if (Eol) {
00113
00114 Eol = FALSE;
00115 } else {
00116
00117 memcpy(Data + (Offset + 1), Data + Offset, (Count - 1 - Offset) * sizeof(DATA));
00118 }
00119 Offset++;
00120 if (Offset == Count) Eol = TRUE;
00121 return Data[retOffset];
00122 }
00123
00124
00125 template <class DATA>
00126 BOOL Array<DATA>::Delete() {
00127 if (Eol) return FALSE;
00128
00129 memcpy(Data + Offset, Data + (Offset + 1), (Count - 1 - Offset) * sizeof(DATA));
00130 Count--;
00131 if (Offset == Count) (Eol) = TRUE;
00132 ReAlloc(Count);
00133 return TRUE;
00134 }
00135
00136
00137 template <class DATA>
00138 BOOL Array<DATA>::Set(DATA x, BOOL _inc) {
00139 if (Eol) return FALSE;
00140 Data[Offset] = x;
00141 if (_inc) {
00142 Offset++;
00143 if (Offset == Count) Eol = TRUE;
00144 }
00145 return TRUE;
00146 }
00147
00148
00149 template <class DATA>
00150 BOOL Array<DATA>::Get(DATA &x, BOOL _inc) {
00151 if (Eol) return FALSE;
00152 x = Data[Offset];
00153 if (_inc) {
00154 Offset++;
00155 if (Offset == Count) Eol = TRUE;
00156 }
00157 return TRUE;
00158 }
00159
00160
00161 template <class DATA>
00162 BOOL Array<DATA>::Get(DATA *&x, BOOL _inc) {
00163 if (Eol) return FALSE;
00164 x = &Data[Offset];
00165 if (_inc) {
00166 Offset++;
00167 if (Offset == Count) Eol = TRUE;
00168 }
00169 return TRUE;
00170 }
00171
00172
00173 template <class DATA>
00174 BOOL Array<DATA>::Seek(int32 _Offset, int fromwhere) {
00175
00176
00177 if (!Count) return FALSE;
00178 switch (fromwhere) {
00179 case SEEK_SET:
00180 (Offset) = 0;
00181 (Eol) = FALSE;
00182 break;
00183 case SEEK_END:
00184 Offset = Count;
00185 Eol = TRUE;
00186 break;
00187 case SEEK_CUR:
00188 break;
00189 default:
00190 SystemCode::RaiseException(ERR_BADARGS);
00191 }
00192 if (_Offset == 0) return TRUE;
00193 if (_Offset < 0) {
00194
00195 _Offset *= -1;
00196 if (Offset < _Offset) {
00197 Offset = 0;
00198 Eol = FALSE;
00199 return FALSE;
00200 }
00201 Offset -= _Offset;
00202 Eol = FALSE;
00203 return TRUE;
00204 }
00205
00206 Offset += _Offset;
00207 if (Offset > Count) {
00208 Offset = Count;
00209 Eol = TRUE;
00210 return FALSE;
00211 }
00212 if (Offset == Count) Eol = TRUE;
00213 return !Eol;
00214 }
00215
00216 template <class DATA>
00217 int Array<DATA>::Find(DATA x) {
00218
00219 int idx = 0;
00220 while (idx < Count) {
00221 if (Data[idx] == x) return idx;
00222 idx++;
00223 }
00224 return ( -1);
00225 }
00226
00227 template <class DATA>
00228 void Array<DATA>::ReAlloc(uint32 size) {
00229 uint32 D;
00230 uint32 OldCount = Count;
00231 if (!size) {
00232 MemFree(Data);
00233 Data = (DATA*)NULL;
00234 Offset = 0;
00235 Count = 0;
00236 A = 0;
00237 Eol = TRUE;
00238 return;
00239 }
00240 Count = size;
00241 if (Offset >= Count) {
00242 Offset = Count;
00243 Eol = TRUE;
00244 }
00245 if (G > 1) {
00246 D = (size / G);
00247 if ((D * G) != size) D++;
00248 if (A != D) {
00249 A = D;
00250 Data = (DATA*)SystemCode::MemReAlloc((PTR)Data, A * G * sizeof(DATA));
00251 }
00252 } else {
00253 Data = (DATA*)SystemCode::MemReAlloc((PTR)Data, Count * sizeof(DATA));
00254 }
00255 if (OldCount < Count) SystemCode::memset(((uint8*)Data) + (OldCount * sizeof(DATA)), 0, (Count - OldCount) * sizeof(DATA));
00256 }
00257
00258 template <class DATA>
00259 void Array<DATA>::SetGranularity(uint32 size) {
00260 if (Count) return;
00261 G = size;
00262 A = 0;
00263 }
00264
00265 template <class DATA>
00266 void Array<DATA>::Sort(BOOL asc) {
00267 if (asc) _qsort_asc(Data, 0, Count - 1); else _qsort_dec(Data, 0, Count - 1);
00268 }
00269
00270 template <class DATA>
00271 void Array<DATA>::_qsort_asc(DATA *b, int left, int right) {
00272 int i, j;
00273 BOOL finish;
00274 DATA p, tmp;
00275 if (right > left) {
00276 i = left;
00277 j = right;
00278 p = b[left];
00279 finish = FALSE;
00280 while (!finish) {
00281 do { i++;} while ((b[i] <= p) && (i <= right));
00282 while ((b[j] >= p) && (j > left)) {j--;}
00283 if (j < i)
00284 finish = TRUE;
00285 else {
00286 tmp = b[i];b[i] = b[j];b[j] = tmp;
00287 }
00288 }
00289 tmp = b[left];
00290 b[left] = b[j];
00291 b[j] = tmp;
00292 _qsort_asc(b, left, j - 1);
00293 _qsort_asc(b, i, right);
00294 }
00295 return;
00296 }
00297
00298 template <class DATA>
00299 void Array<DATA>::_qsort_dec(DATA *b, int left, int right) {
00300 int i, j;
00301 BOOL finish;
00302 DATA p, tmp;
00303 if (right > left) {
00304 i = left;
00305 j = right;
00306 p = b[left];
00307 finish = FALSE;
00308 while (!finish) {
00309 do { i++;} while ((b[i] >= p) && (i <= right));
00310 while ((b[j] <= p) && (j > left)) {j--;}
00311 if (j < i)
00312 finish = TRUE;
00313 else {
00314 tmp = b[i];b[i] = b[j];b[j] = tmp;
00315 }
00316 }
00317 tmp = b[left];
00318 b[left] = b[j];
00319 b[j] = tmp;
00320 _qsort_dec(b, left, j - 1);
00321 _qsort_dec(b, i, right);
00322 }
00323 return;
00324 }