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