00001 #ifndef _T_VAL_LIST_T_HH
00002 #define _T_VAL_LIST_T_HH
00003
00004 #include <stdlib.h>
00005 #include "TBoundsException.hh"
00006 #include "TMemoryException.hh"
00007
00008 #define T_ABS(x) (x < 0 ? -x: x)
00009
00010
00011
00012
00013 template <class T>
00014 class TValListEntryT
00015 {
00016 public:
00017
00019 TValListEntryT<T> *prev;
00020
00022 TValListEntryT<T> *next;
00023
00025 T data;
00026 };
00027
00028
00035 template <class T>
00036 class TValListT
00037 {
00038 public:
00039
00043 TValListT () { Reset (); }
00044
00048 TValListT (TValListT<T> &list) { Copy (list); }
00049
00053 ~TValListT () { Clear (); }
00054
00058 void Append (T a);
00059
00066 void Apply (void (*fn)(T *, void *), void *d);
00067
00071 void Clear ();
00072
00076 inline int Entries () const { return myNumElements; }
00077
00082 inline T First () { return myFirst->data; }
00083
00087 void Insert (T a, int i = 0);
00088
00093 inline T Last () { return myLast->data; }
00094
00098 T Remove (int i = 0);
00099
00103 T RemoveLast ();
00104
00110 void Sort (bool reverse = false);
00111
00116 T& operator[](int i);
00117
00121 TValListT<T>& operator=(const TValListT<T> &list);
00122
00123
00124 private:
00125
00129 inline void Reset ()
00130 {
00131 myFirst = NULL;
00132 myLast = NULL;
00133 myCurrentPtr = NULL;
00134 myCurrentNum = 0;
00135 myNumElements = 0;
00136 }
00137
00141 void UpdateCurrent (int i);
00142
00147 void Copy (const TValListT<T> &list);
00148
00149
00150
00151 TValListEntryT<T> *myFirst;
00152
00153
00154 TValListEntryT<T> *myLast;
00155
00156
00157
00158 TValListEntryT<T> *myCurrentPtr;
00159
00160
00161
00162 int myCurrentNum;
00163
00164
00165 int myNumElements;
00166 };
00167
00168
00169 template <class T>
00170 void TValListT<T>::Append (T a)
00171 {
00172 TValListEntryT<T> *entry;
00173
00174 entry = new TValListEntryT<T>;
00175 entry->data = a;
00176
00177 if (myNumElements)
00178 {
00179 myLast->next = entry;
00180 entry->prev = myLast;
00181 myLast = entry;
00182 }
00183 else
00184 {
00185 myFirst = entry;
00186 myLast = entry;
00187 myCurrentPtr = myFirst;
00188 myCurrentNum = 0;
00189 }
00190
00191 myNumElements++;
00192 }
00193
00194
00195 template <class T>
00196 void TValListT<T>::Apply (void (*fn)(T *, void *), void *d)
00197 {
00198 TValListEntryT<T> *entry = myFirst;
00199
00200 for (int i = 0; i < myNumElements; i++)
00201 {
00202 fn (&entry->data, d);
00203 entry = entry->next;
00204 }
00205 }
00206
00207
00208 template <class T>
00209 void TValListT<T>::Clear ()
00210 {
00211 TValListEntryT<T> *entry = myFirst, *tmp_entry;
00212
00213 for (int i = 0; i < myNumElements; i++)
00214 {
00215 tmp_entry = entry;
00216 entry = entry->next;
00217 delete tmp_entry;
00218 }
00219
00220 Reset ();
00221 }
00222
00223
00224 template <class T>
00225 void TValListT<T>::Insert (T a, int i)
00226 {
00227 TValListEntryT<T> *entry;
00228
00229
00230 if (i == myNumElements)
00231 {
00232 Append (a);
00233 return;
00234 }
00235
00236 #ifdef TOOLS_BOUND_CHECK
00237 if (i >= myNumElements || i < 0)
00238 throw TBoundsException ();
00239 #endif
00240
00241 entry = new TValListEntryT<T>;
00242 entry->data = a;
00243
00244
00245 if (! i)
00246 {
00247 myFirst->prev = entry;
00248 entry->next = myFirst;
00249 myFirst = entry;
00250 myCurrentPtr = myFirst;
00251 myCurrentNum = 0;
00252 }
00253 else
00254 {
00255 UpdateCurrent (i);
00256 entry->prev = myCurrentPtr->prev;
00257 entry->next = myCurrentPtr;
00258 myCurrentPtr->prev->next = entry;
00259 myCurrentPtr->prev = entry;
00260 myCurrentPtr = entry;
00261
00262 }
00263
00264 myNumElements++;
00265 }
00266
00267
00268 template <class T>
00269 T TValListT<T>::Remove (int i)
00270 {
00271 #ifdef TOOLS_BOUND_CHECK
00272 if (i >= myNumElements || i < 0)
00273 throw TBoundsException ();
00274 #endif
00275
00276
00277 if (i == (myNumElements - 1))
00278 return RemoveLast ();
00279
00280 TValListEntryT<T> *entry;
00281 T data;
00282
00283
00284 if (! i)
00285 {
00286 entry = myFirst;
00287 data = myFirst->data;
00288 myFirst = myFirst->next;
00289 myCurrentPtr = myFirst;
00290 myCurrentNum = 0;
00291 }
00292 else
00293 {
00294 UpdateCurrent (i);
00295 entry = myCurrentPtr;
00296 data = myCurrentPtr->data;
00297 myCurrentPtr->prev->next = myCurrentPtr->next;
00298 myCurrentPtr->next->prev = myCurrentPtr->prev;
00299 myCurrentPtr = myCurrentPtr->next;
00300
00301 }
00302
00303 delete entry;
00304 myNumElements--;
00305
00306 return data;
00307 }
00308
00309
00310 template <class T>
00311 T TValListT<T>::RemoveLast ()
00312 {
00313 #ifdef TOOLS_BOUND_CHECK
00314 if (! myNumElements)
00315 throw TBoundsException ();
00316 #endif
00317
00318 TValListEntryT<T> *entry = myLast;
00319 T data = myLast->data;
00320
00321 if (myNumElements == 1)
00322 Reset ();
00323 else
00324 {
00325 myLast = myLast->prev;
00326 myNumElements--;
00327 if (myCurrentNum >= myNumElements)
00328 {
00329 myCurrentPtr = myFirst;
00330 myCurrentNum = 0;
00331 }
00332 }
00333
00334 delete entry;
00335 return data;
00336 }
00337
00338
00339
00340 template <class T>
00341 void TValListT<T>::Sort (bool reverse)
00342 {
00343 }
00344
00345
00346 template <class T>
00347 T& TValListT<T>::operator[](int i)
00348 {
00349 #ifdef TOOLS_BOUND_CHECK
00350 if (i >= myNumElements || i < 0)
00351 throw TBoundsException ();
00352 #endif
00353
00354 UpdateCurrent (i);
00355
00356 return myCurrentPtr->data;
00357 }
00358
00359
00360 template <class T>
00361 TValListT<T>& TValListT<T>::operator=(const TValListT<T> &list)
00362 {
00363
00364 if (&list != this)
00365 {
00366 Clear ();
00367 Copy (list);
00368 }
00369
00370 return *this;
00371 }
00372
00373
00374 template <class T>
00375 void TValListT<T>::Copy (const TValListT<T> &list)
00376 {
00377 TValListEntryT<T> *entry = NULL, *prev = NULL;
00378 TValListEntryT<T> *entry_orig = list.myFirst;
00379
00380 myFirst = NULL;
00381 myNumElements = list.myNumElements;
00382
00383 for (int i = 0; i < myNumElements; i++)
00384 {
00385 entry = new TValListEntryT<T>;
00386
00387
00388 if (prev)
00389 prev->next = entry;
00390
00391 entry->prev = prev;
00392 entry->data = entry_orig->data;
00393 prev = entry;
00394
00395 entry_orig = entry_orig->next;
00396
00397
00398 if (! i)
00399 myFirst = entry;
00400 }
00401
00402 myCurrentPtr = myFirst;
00403 myCurrentNum = 0;
00404 myLast = entry;
00405 }
00406
00407
00408 template <class T>
00409 void TValListT<T>::UpdateCurrent (int i)
00410 {
00411 int l_dist = (myNumElements - 1) - i;
00412 int c_dist = T_ABS (myCurrentNum - i);
00413
00414
00415 if (i <= l_dist)
00416 {
00417
00418 if (i < c_dist)
00419 {
00420 myCurrentPtr = myFirst;
00421 myCurrentNum = 0;
00422 }
00423 }
00424 else
00425 {
00426
00427 if (l_dist < c_dist)
00428 {
00429 myCurrentPtr = myLast;
00430 myCurrentNum = (myNumElements - 1);
00431 }
00432 }
00433
00434
00435 if (myCurrentNum < i)
00436 {
00437 for (; myCurrentNum < i; myCurrentNum++)
00438 myCurrentPtr = myCurrentPtr->next;
00439 }
00440
00441
00442 if (myCurrentNum > i)
00443 {
00444 for (; myCurrentNum > i; myCurrentNum--)
00445 myCurrentPtr = myCurrentPtr->prev;
00446 }
00447 }
00448
00449 #endif // _T_VAL_LIST_T_HH