00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00023 #ifndef INCLUDE_LISTE_GENERIQUE_H
00024 #define INCLUDE_LISTE_GENERIQUE_H
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <stdio.h>
00034 #include <math.h>
00035
00036 typedef enum _ETypeStart
00037 {
00038 list_current = 1,
00039 list_first,
00040 list_last,
00041 list_before,
00042 list_after
00043 } ETypeStart;
00044
00045 #include "MyException.h"
00046
00081 template <class T> class MyListItem
00082 {
00083 public:
00084 T *elem;
00085 MyListItem<T> *after,*before;
00086 BOOL selfUnAlloc;
00087
00088 MyListItem()
00089 {
00090 elem=NULL;
00091 selfUnAlloc=FALSE;
00092 ZeroLink();
00093 }
00094
00095 MyListItem(T *_elem,BOOL _selfAlloc,BOOL _selfUnAlloc)
00096 {
00097 New(_elem,_selfAlloc,_selfUnAlloc);
00098 }
00099
00100 void ZeroLink()
00101 {
00102 after=NULL;
00103 before=NULL;
00104 }
00105
00106 MyListItem(T *_elem) { New (_elem,FALSE,FALSE); }
00107 MyListItem(T &_elem) { New (&_elem,TRUE,TRUE); }
00108
00109 ~MyListItem()
00110 {
00111 Delete();
00112 }
00113
00117 void Delete()
00118 {
00119 if (elem&&selfUnAlloc) delete elem;
00120 }
00121
00125 void New (T *_elem,BOOL _selfAlloc,BOOL _selfUnAlloc)
00126 {
00127 selfUnAlloc = _selfUnAlloc;
00128 if (_selfAlloc)
00129 {
00130 elem = new T;
00131 *elem=*_elem;
00132 }
00133 else elem = _elem;
00134 if (!elem) throw MyExceptionMemory("MyList","NewElem",sizeof(T));
00135 after=NULL;
00136 before=NULL;
00137 }
00138
00139 void New (T *elem) { New (elem,FALSE,FALSE); }
00140 void New (T &elem) { New (&elem,TRUE,TRUE); }
00141
00142
00143 };
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 template <class T> class MyList;
00157
00158 template <class T> class MyListIterator
00159 {
00160 private:
00161 MyListItem<T> *current;
00162 MyList<T> *list;
00163 int numCurrent;
00164
00165 public:
00167 MyListIterator()
00168 {
00169 Bind(NULL);
00170 }
00171 MyListIterator(MyList<T> *_list)
00172 {
00173 Bind(_list);
00174 }
00175
00176 BOOL Bind(MyList<T> *_list)
00177 {
00178 list = _list;
00179 Zero();
00180 if (!_list) return FALSE;
00181 return TRUE;
00182 }
00183
00184 void operator=(MyListIterator &src)
00185 {
00186 current =src.current;
00187 list = src.list;
00188 numCurrent = src.numCurrent;
00189 }
00190
00192 void Zero()
00193 {
00194 current=NULL;
00195 numCurrent=-1;
00196 }
00197
00198 MyListItem<T> * GetCurrent()
00199 {
00200 return current;
00201 }
00202
00210 int GetIndex()
00211 {
00212 return numCurrent;
00213 }
00214
00215
00216
00217 BOOL MoveFirst()
00218 {
00219 if (!current) return FALSE;
00220 Supr(current,FALSE);
00221 return AddFirst(current)?TRUE:FALSE;
00222 }
00223
00224 BOOL MoveLast()
00225 {
00226 if (!current) return FALSE;
00227 Supr(current,FALSE);
00228 return AddLast(current)?TRUE:FALSE;;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 MyListItem<T> * AddBefore (T *elem,BOOL selfAlloc,BOOL selfUnAlloc)
00249 {
00250 MyListItem<T> * item = new MyListItem<T>(elem,selfAlloc,selfUnAlloc);
00251 return AddBefore(item);
00252 }
00253
00254 MyListItem<T> * AddBefore(MyListItem<T> * item)
00255 {
00256 if (!item) return NULL;
00257 if (!current)
00258 {
00259 if (!list->first && !list->last)
00260 {
00261 list->first=list->last=current=item;
00262 numCurrent=0;
00263 }
00264 else return NULL;
00265 }
00266 else
00267 {
00268 if (current==list->first)
00269 {
00270 list->first->before = item;
00271 item->after =list->first;
00272 list->first = current = item;
00273 }
00274 else
00275 {
00276 item->before = current->before;
00277 current->before->after = item;
00278 current->before = item;
00279 item->after = current;
00280 current = item;
00281 }
00282 }
00283 list->nbElem ++;
00284 return current;
00285 }
00286
00287 MyListItem<T> * AddFirst (T *elem,BOOL selfAlloc,BOOL selfUnAlloc)
00288 {
00289 MyListItem<T> * item = new MyListItem<T>(elem,selfAlloc,selfUnAlloc);
00290 return AddFirst(item);
00291 }
00292
00293 MyListItem<T> * AddFirst (MyListItem<T> * item)
00294 {
00295 if (!item) return NULL;
00296 if (!list->first) list->first=list->last=current=item;
00297 else
00298 {
00299 list->first->before = item;
00300 item->after = list->first;
00301 list->first = current = item;
00302 }
00303 numCurrent=0;
00304 list->nbElem ++;
00305 return item;
00306 }
00307
00308 MyListItem<T> * AddLast (T *elem,BOOL selfAlloc,BOOL selfUnAlloc)
00309 {
00310 MyListItem<T> * item = new MyListItem<T>(elem,selfAlloc,selfUnAlloc);
00311 return AddLast(item);
00312 }
00313
00314 MyListItem<T> * AddLast (MyListItem<T> * item)
00315 {
00316 if (!item) return NULL;
00317 if (!list->last) current = list->first = list->last = item;
00318 else
00319 {
00320 list->last->after = item;
00321 item->before = list->last;
00322 list->last = current = item;
00323 }
00324 numCurrent=list->nbElem;
00325 list->nbElem ++;
00326 return item;
00327 }
00328
00329 MyListItem<T> * AddAfter (T *elem,BOOL selfAlloc,BOOL selfUnAlloc)
00330 {
00331 MyListItem<T> * item = new MyListItem<T>(elem,selfAlloc,selfUnAlloc);
00332 return AddAfter(item);
00333 }
00334
00335 MyListItem<T> * AddAfter (MyListItem<T> * item)
00336 {
00337 if (!item) return FALSE;
00338 if (!current)
00339 {
00340 if (!list->first && !list->last) list->first=list->last=current=item;
00341 else return FALSE;
00342 }
00343 else
00344 {
00345 if (current==list->last)
00346 {
00347 list->last->after = item;
00348 item->before = list->last;
00349 list->last = current = item;
00350 }
00351 else
00352 {
00353 item->after = current->after;
00354 current->after->before = current->after = item;
00355 item->before = current;
00356 current = item;
00357 }
00358 }
00359 numCurrent++;
00360 list->nbElem ++;
00361 return item;
00362 }
00363
00365 MyListItem<T> * AddFirst (T *elem) { return AddFirst(elem,FALSE,FALSE); }
00366 MyListItem<T> * AddFirst (T &elem) { return AddFirst(&elem,TRUE,TRUE); }
00367 T * AddNewFirst()
00368 {
00369 T *elem = new T;
00370 AddFirst(elem,FALSE,TRUE);
00371 return elem;
00372 }
00373
00375 MyListItem<T> * AddLast (T *elem) { return AddLast(elem,FALSE,FALSE); }
00376 MyListItem<T> * AddLast (T &elem) { return AddLast(&elem,TRUE,TRUE); }
00377 T * AddNewLast()
00378 {
00379 T *elem = new T;
00380 AddLast(elem,FALSE,TRUE);
00381 return elem;
00382 }
00383
00385 MyListItem<T> * AddBefore (T *elem) { return AddBefore(elem,FALSE,FALSE); }
00386 MyListItem<T> * AddBefore (T &elem) { return AddBefore(&elem,TRUE,TRUE); }
00387 T * AddNewBefore()
00388 {
00389 T *elem = new T;
00390 AddBefore(elem,FALSE,TRUE);
00391 return elem;
00392 }
00393
00395 MyListItem<T> * AddAfter (T *elem) { return AddAfter(elem,FALSE,FALSE); }
00396 MyListItem<T> * AddAfter (T &elem) { return AddAfter(&elem,TRUE,TRUE); }
00397 T * AddNewAfter()
00398 {
00399 T *elem = new T;
00400 AddAfter(elem,FALSE,TRUE);
00401 return elem;
00402 }
00403
00404
00405
00407 BOOL SuprFirst (BOOL withItem=TRUE)
00408 {
00409 if (!list->first) return FALSE;
00410 MyListItem<T> * temp;
00411
00412 temp = list->first->after;
00413 if (withItem) delete list->first;
00414 else list->first->ZeroLink();
00415
00416
00417 if (!temp)
00418 {
00419 list->first = list->last = NULL;
00420 Zero();
00421 }
00422 else
00423 {
00424 if (current==list->first) current = temp;
00425 else numCurrent--;
00426 temp->before = NULL;
00427 list->first = temp;
00428 }
00429 list->nbElem --;
00430 return TRUE;
00431 }
00432
00434 BOOL SuprLast (BOOL withItem=TRUE)
00435 {
00436 if (!list->last) return FALSE;
00437 MyListItem<T> *temp;
00438 temp = list->last->before;
00439 if (withItem) delete list->last;
00440 else list->last->ZeroLink();
00441
00442
00443 if (!temp)
00444 {
00445 list->first = list->last = NULL;
00446 Zero();
00447 }
00448 else
00449 {
00450 if (list->last==current)
00451 {
00452 current = temp;
00453 numCurrent--;
00454 }
00455 temp->after = NULL;
00456 list->last = temp;
00457 }
00458 list->nbElem --;
00459 return TRUE;
00460 }
00461
00463 void SuprAll()
00464 {
00465 GoFirst();
00466 while (More()) list->i.Supr();
00467 list->Zero();
00468 Zero();
00469 }
00470
00472 BOOL Supr (MyListItem<T> *item,BOOL withItem=TRUE)
00473 {
00474 if (!item) return FALSE;
00475
00476 MyListIterator<T> j=*this;
00477 for (j=0;j.More();j++)
00478 {
00479 if (j.GetCurrent()==item) return j.Supr(withItem);
00480 }
00481 return FALSE;
00482 }
00483
00485 BOOL Supr(BOOL withItem=TRUE)
00486 {
00487 if (!current) return FALSE;
00488 MyListItem<T> * lAfter,*lBefore,*lOld;
00489 lAfter = current->after;
00490 lBefore = current->before;
00491 lOld = current;
00492
00493 if (!lBefore && !lAfter)
00494 {
00495 list->first = list->last = NULL;
00496 Zero();
00497 }
00498 else
00499 {
00500 if (lBefore)
00501 {
00502 lBefore->after=lAfter;
00503 if (lAfter)
00504 {
00505 lAfter->before = lBefore;
00506 current = lAfter;
00507 }
00508 else
00509 {
00510 list->last = current = lBefore;
00511 numCurrent--;
00512 }
00513 }
00514 else
00515 {
00516 current = list->first = lAfter;
00517 lAfter->before = NULL;
00518 numCurrent--;
00519 }
00520 }
00521 if (withItem) delete lOld;
00522 else lOld->ZeroLink();
00523 list->nbElem --;
00524 return TRUE;
00525 }
00526
00528 BOOL SuprIndex(int index,BOOL withItem=TRUE)
00529 {
00530 if (!GoIndex(list->first,index)) return FALSE;
00531 return Supr(withItem);
00532 }
00533
00534
00535
00537 BOOL GoTo(MyListItem<T> *item)
00538 {
00539 if (!item) return FALSE;
00540 for (GoFirst();More();GoAfter())
00541 {
00542 if (GetCurrent()==item) return TRUE;
00543 }
00544 return FALSE;
00545 }
00546
00548 BOOL GoTo(T elem)
00549 {
00550 for (GoFirst();More();GoAfter())
00551 {
00552 if (GetElem()==elem) return TRUE;
00553 }
00554 return FALSE;
00555 }
00556
00558 BOOL GoAfter()
00559 {
00560 if (current) current = current->after;
00561 if (current)
00562 {
00563 numCurrent = numCurrent == -1 ? -1 : numCurrent+1;
00564 return TRUE ;
00565 }
00566 else
00567 {
00568 numCurrent = -1;
00569 return FALSE;
00570 }
00571 }
00572
00574 BOOL GoBefore ()
00575 {
00576 if (current) current = current->before;
00577 if (current)
00578 {
00579 numCurrent = numCurrent == -1 ? -1 : numCurrent-1;
00580 return TRUE;
00581 }
00582 else
00583 {
00584 numCurrent = -1;
00585 return FALSE;
00586 }
00587 }
00588
00590 BOOL GoFirst ()
00591 {
00592 current = list->first;
00593 numCurrent = current? 0 : -1;
00594 return current? TRUE : FALSE;
00595 }
00596
00598 BOOL GoIndex (ETypeStart start,int nb)
00599 {
00600 BOOL isUp;
00601 isUp = nb<0 ? FALSE : TRUE ;
00602 nb = labs(nb);
00603 switch (start)
00604 {
00605 case list_current: break;
00606 case list_first:
00607 if (numCurrent != -1)
00608 {
00609 nb = numCurrent-nb;
00610 isUp = nb<=0;
00611 nb = labs(nb);
00612 }
00613 else
00614 {
00615 isUp = TRUE;
00616 GoFirst();
00617 }
00618 break;
00619 case list_last:
00620 if (numCurrent != -1)
00621 {
00622 nb = list->nbElem-numCurrent-nb;
00623 isUp = nb>=0;
00624 nb = labs(nb);
00625 }
00626 else
00627 {
00628 isUp = FALSE;
00629 GoLast();
00630 }
00631 break;
00632 case list_before: isUp = FALSE; break;
00633 case list_after: isUp = TRUE; break;
00634 default:
00635 return FALSE;
00636 }
00637 for (int i=0;i<nb;i++)
00638 {
00639 if (More())
00640 {
00641 if (isUp) GoAfter();
00642 else GoBefore();
00643 } else return FALSE;
00644 }
00645 return TRUE;
00646 }
00647
00649 BOOL GoLast ()
00650 {
00651 current = list->last;
00652 numCurrent = current? list->nbElem -1 : -1;
00653 return current? TRUE : FALSE;
00654 }
00655
00656
00657
00658
00659
00660
00672 T & GetElem (int index=-1)
00673 {
00674 if (index!=-1) GoIndex(list_first,index);
00675 if (!current) return *list->elemNull;
00676 return *current->elem;
00677 }
00678
00679 T * GetElemPtr ()
00680 {
00681 if (!current) return list->elemNull;
00682 return current->elem;
00683 }
00684
00696 T * GetElemPtr (int index)
00697 {
00698 if (!GoIndex(list_first,index)) return list->elemNull;
00699 if (!current) return list->elemNull;
00700 return current->elem;
00701 }
00702
00704 BOOL More ()
00705 {
00706 return current ? TRUE : FALSE;
00707 }
00708
00710 BOOL IsOnLast()
00711 {
00712 return (current==list->last)? TRUE : FALSE;
00713 }
00714
00716 BOOL IsOnFirst()
00717 {
00718 return (current==list->first)? TRUE : FALSE;
00719 }
00720
00721 MyListItem<T> * operator += (T *elem)
00722 {
00723 return AddLast(elem);
00724 }
00725
00726 MyListItem<T> * operator += (T elem)
00727 {
00728 return AddLast(elem);
00729 }
00730
00731 BOOL operator = (int index)
00732 {
00733 if (index>=0) return GoIndex(list_first,index);
00734 else return GoIndex(list_last,-index+1);
00735 }
00736
00737 BOOL operator++ (int)
00738 {
00739 return GoAfter();
00740 }
00741
00742 BOOL operator-- (int)
00743 {
00744 return GoBefore();
00745 }
00746
00747 T * operator () (int num=-1)
00748 {
00749 return GetElemPtr(num);
00750 }
00751
00752 T & operator [] (int num)
00753 {
00754 if (num<0)
00755 {
00756 if (!GoIndex(list_last,-num)) return *list->elemNull;
00757 }
00758 else
00759 {
00760 if (!GoIndex(list_first,num)) return *list->elemNull;
00761 }
00762 return GetElem();
00763 }
00764 };
00765
00766 template <class T> class MyList
00767 {
00768 public:
00769 MyListIterator<T> i;
00770 T * elemNull;
00771 MyListItem<T> *first;
00772 MyListItem<T> *last;
00773 int nbElem;
00774
00775
00777 MyList ()
00778 {
00779 Zero();
00780 i.Bind(this);
00781
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00797 ~MyList ()
00798 {
00799 i.SuprAll();
00800 }
00801
00803 void Zero()
00804 {
00805 first = NULL;
00806 last = NULL;
00807 nbElem = 0;
00808 }
00809
00811 int GetNbElem()
00812 {
00813 return nbElem;
00814 }
00815
00816 MyList<T> & operator = (MyList<T> &source)
00817 {
00818 i.SuprAll();
00819 *this+= source;
00820 return *this;
00821 }
00822
00823 MyList<T> & operator += (MyList<T> &source)
00824 {
00825 for (source.i=0;source.i.More();source.i++) i+= source.i.GetElem();
00826 return *this;
00827 }
00828
00830 BOOL Save (FILE *fich)
00831 {
00832 if (!fich) return FALSE;
00833
00834 fprintf(fich,"%d",nbElem);
00835 MyListIterator<T> i(this);
00836 T *item;
00837
00838 for (i=0;i.More();i++)
00839 {
00840 item = i.GetElemPtr();
00841 if (item)
00842 if (!fwrite ((void *) item,sizeof(T),1,fich)) return FALSE;
00843 }
00844 return TRUE;
00845 }
00846
00848 BOOL Load (FILE *fich)
00849 {
00850 if (!fich) return FALSE;
00851
00852 int nb;
00853 fscanf(fich,"%d",&nb);
00854 T elem;
00855 MyListIterator<T> i(this);
00856 for (int x=0;x<nb;x++)
00857 {
00858 if (!fread ((void *) &elem,sizeof(T),1,fich))return FALSE;
00859 if (!i.AddAfter(elem)) return FALSE;
00860 }
00861 return TRUE;
00862 }
00863
00869 void SetCompareFunction (int (* fonction)(T * elem1,T * elem2))
00870 {
00871 FoncCompare = fonction;
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 };
00903
00907 template <class T> class MyStack : public MyList<T>
00908 {
00909 public:
00910 MyStack() : MyList<T>() {}
00911
00912 BOOL Push(T elem)
00913 {
00914 return i.AddFirst(elem)?TRUE:FALSE;
00915 }
00916
00917 T Pop()
00918 {
00919 if (i.GoFirst())
00920 {
00921 T elem = i.GetElem();
00922 i.SuprFirst();
00923 return elem;
00924 }
00925 return *elemNull;
00926 }
00927
00928 T Peek()
00929 {
00930 if (i.GoFirst()) return i.GetElem();
00931 return *elemNull;
00932 }
00933
00934 BOOL FrontPush(T elem)
00935 {
00936 return i.AddLast(elem);
00937 }
00938
00939 T FrontPop()
00940 {
00941 if (i.GoLast())
00942 {
00943 T elem = i.GetElem();
00944 i.SuprLast();
00945 return elem;
00946 }
00947 return *elemNull;
00948 }
00949
00950 T FrontPeek()
00951 {
00952 if (i.GoLast()) return i.GetElem();
00953 return *elemNull;
00954 }
00955 };
00956
00957
00958
00959 template <class T> int DefaultFoncCompare (T elem1,T elem2)
00960 {
00961 return memcmp((void *)elem1,(void *)elem2,sizeof(T));
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992 #endif