00001
00002
00003 #ifndef NotCopyable
00004
00005
00006 template <class U, unsigned int pow2, class SearchPolicy>
00007 ChainedList<U, pow2, SearchPolicy>::ChainedList(const ChainedList & copy)
00008 {
00009 unsigned int i;
00010 mbUseBlocks = copy.mbUseBlocks;
00011 mbIntegrity = copy.mbIntegrity;
00012 mlNumberOfNodes = copy.mlNumberOfNodes;
00013 mlNumberOfBlocks = copy.mlNumberOfBlocks;
00014
00015 if (mbUseBlocks)
00016 {
00017
00018 if (copy.mpxBlock == NULL)
00019 {
00020 mpxFirst = mpxLast = mpxCurrent = NULL;
00021 mpxBlock = mpxBLast = NULL;
00022 return;
00023 }
00024
00025
00026 LinearBlock<ChainedBS> * pBlock = new LinearBlock<ChainedBS>;
00027 LinearBlock<ChainedBS> * copyBlock = copy.mpxBlock;
00028
00029 if (pBlock == NULL) return;
00030
00031
00032 mpxBlock = pBlock;
00033 mpxBlock->spxPrevious = NULL;
00034 mpxBlock->spxNext = NULL;
00035 mpxBLast = pBlock;
00036 mpxBlock->soUsed = copy.mpxBlock->soUsed;
00037
00038
00039 for (i=1; i < mlNumberOfBlocks; i++)
00040 {
00041 if (!pBlock->CreateNewBlock()) return;
00042 pBlock->soUsed = copyBlock->soUsed;
00043 pBlock = pBlock->spxNext;
00044 copyBlock = copyBlock->spxNext;
00045 mpxBLast = pBlock;
00046 }
00047
00048
00049 Node * pNode = mpxBlock->GetData();
00050
00051 mpxFirst = pNode;
00052 mpxFirst->mpxPrevious = NULL;
00053 mpxCurrent = NULL;
00054 pBlock = mpxBlock;
00055
00056 for (i=0; i < mlNumberOfBlocks; i++)
00057 {
00058 pNode = pBlock->GetData();
00059 for (unsigned int j=0; j < ChainedBS; j++)
00060 {
00061 pNode->mpxPrevious = mpxCurrent;
00062 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00063 mpxCurrent = pNode;
00064 pNode ++;
00065 }
00066 pBlock = pBlock->spxNext;
00067 }
00068
00069
00070 Node * copyNode = copy.mpxFirst;
00071 pNode = mpxFirst;
00072
00073 for (i=0; i < mlNumberOfNodes; i++)
00074 {
00075 if (pNode == NULL || copyNode == NULL) return;
00076 pNode->Set(*copyNode->mpuElement);
00077 pNode = pNode->mpxNext;
00078 copyNode = copyNode->mpxNext;
00079 }
00080
00081
00082 if (pNode!=NULL) mpxLast = pNode->mpxPrevious; else mpxLast = mpxCurrent;
00083 mpxCurrent = pNode;
00084 mpxLast->mpxNext = NULL;
00085 mbIntegrity = true;
00086 }
00087 else
00088 {
00089
00090 Node * pNode0 = NULL;
00091 Node * pNode;
00092 Node * pCopy = copy.mpxFirst;
00093 for (unsigned int i = 0; i < mlNumberOfNodes; i++)
00094 {
00095 pNode = new Node;
00096
00097 if (pNode == NULL) return;
00098 if (i==0) mpxFirst = pNode;
00099 pNode->mpxPrevious = pNode0;
00100 if (pNode->mpxPrevious != NULL) pNode->mpxPrevious->mpxNext = pNode;
00101
00102
00103 if (pCopy == NULL) return;
00104
00105 pNode->Set(*pCopy->mpuElement);
00106 pCopy = pCopy->mpxNext;
00107 pNode0 = pNode;
00108 }
00109
00110
00111 mpxLast = pNode;
00112 mpxCurrent = mpxLast;
00113 mpxBlock = mpxBLast = NULL;
00114
00115 }
00116 }
00117
00118 template <class U, unsigned int pow2, class SearchPolicy>
00119 ChainedList<U, pow2, SearchPolicy>& ChainedList<U, pow2, SearchPolicy>::operator =(const ChainedList & copy)
00120 {
00121 if (© == this) return (*this);
00122
00123 if (mpxBlock != NULL)
00124 if (!mpxBlock->DeleteAll()) return (*this);
00125
00126 unsigned int i;
00127 if (!mbUseBlocks)
00128 {
00129 Node * pNode = mpxFirst;
00130
00131
00132 if (mpxFirst!=NULL)
00133 {
00134
00135 while (pNode!=NULL)
00136 {
00137 mpxFirst = pNode->mpxNext;
00138 delete pNode;
00139 pNode = mpxFirst;
00140 }
00141 }
00142
00143 }
00144
00145 mbUseBlocks = copy.mbUseBlocks;
00146 mbIntegrity = copy.mbIntegrity;
00147 mlNumberOfNodes = copy.mlNumberOfNodes;
00148 mlNumberOfBlocks = copy.mlNumberOfBlocks;
00149
00150 if (mbUseBlocks)
00151 {
00152
00153 if (copy.mpxBlock == NULL)
00154 {
00155 mpxFirst = mpxLast = mpxCurrent = NULL;
00156 mpxBlock = mpxBLast = NULL;
00157 return (*this);
00158 }
00159
00160
00161 LinearBlock<ChainedBS> * pBlock = new LinearBlock<ChainedBS>;
00162 LinearBlock<ChainedBS> * copyBlock = copy.mpxBlock;
00163
00164 if (pBlock == NULL) return (*this);
00165
00166
00167 mpxBlock = pBlock;
00168 mpxBlock->spxPrevious = NULL;
00169 mpxBlock->spxNext = NULL;
00170 mpxBLast = pBlock;
00171 mpxBlock->soUsed = copy.mpxBlock->soUsed;
00172
00173
00174 for (i=1; i < mlNumberOfBlocks; i++)
00175 {
00176 if (!pBlock->CreateNewBlock()) return (*this);
00177 pBlock->soUsed = copyBlock->soUsed;
00178 pBlock = pBlock->spxNext;
00179 copyBlock = copyBlock->spxNext;
00180 mpxBLast = pBlock;
00181 }
00182
00183
00184 Node * pNode = mpxBlock->GetData();
00185
00186 mpxFirst = pNode;
00187 mpxFirst->mpxPrevious = NULL;
00188 mpxCurrent = NULL;
00189 pBlock = mpxBlock;
00190
00191 for (i=0; i < mlNumberOfBlocks; i++)
00192 {
00193 pNode = pBlock->GetData();
00194 for (unsigned int j=0; j < ChainedBS; j++)
00195 {
00196 pNode->mpxPrevious = mpxCurrent;
00197 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00198 mpxCurrent = pNode;
00199 pNode ++;
00200 }
00201 pBlock = pBlock->spxNext;
00202 }
00203
00204
00205 Node * copyNode = copy.mpxFirst;
00206 pNode = mpxFirst;
00207
00208 for (i=0; i < mlNumberOfNodes; i++)
00209 {
00210 if ( pNode == NULL || copyNode == NULL) return (*this);
00211
00212 pNode->Set(copyNode->Get());
00213 pNode = pNode->mpxNext;
00214 copyNode = copyNode->mpxNext;
00215 }
00216
00217
00218 if (pNode!=NULL) mpxLast = pNode->mpxPrevious; else mpxLast = mpxCurrent;
00219 mpxCurrent = pNode;
00220 mpxLast->mpxNext = NULL;
00221 mbIntegrity = true;
00222 }
00223 else
00224 {
00225 Node * pNode = NULL;
00226
00227
00228 Node * pNode0 = NULL;
00229 Node * pCopy = copy.mpxFirst;
00230 for (unsigned int i = 0; i < mlNumberOfNodes; i++)
00231 {
00232 pNode = new Node;
00233
00234 if (pNode == NULL) return (*this);
00235 if (i==0) mpxFirst = pNode;
00236 pNode->mpxPrevious = pNode0;
00237 if (pNode->mpxPrevious != NULL) pNode->mpxPrevious->mpxNext = pNode;
00238
00239
00240 if (pCopy == NULL) return (*this);
00241
00242 pNode->Set(pCopy->Get());
00243 pCopy = pCopy->mpxNext;
00244 pNode0 = pNode;
00245 }
00246
00247
00248 mpxLast = pNode;
00249 mpxCurrent = mpxLast;
00250 mpxBlock = mpxBLast = NULL;
00251
00252 }
00253
00254 return (*this);
00255 }
00256
00257 template <class U, unsigned int pow2, class SearchPolicy>
00258 bool ChainedList<U, pow2, SearchPolicy>::Add(DefaultConstParamType a, const unsigned int& pos)
00259 {
00260 return Add(new U(a), pos);
00261 }
00262
00263 #endif
00264
00265
00266
00267 template <class U, unsigned int pow2, class SearchPolicy>
00268 ChainedList<U, pow2, SearchPolicy>::ChainedList() : mlNumberOfNodes(0), mlNumberOfBlocks(0), mpxBlock(NULL), mpxFirst(NULL), mpxLast(NULL), mpxCurrent(NULL), mbIntegrity(true), mpxBLast(NULL)
00269 {
00270 mbUseBlocks = (pow2==0) ? false: true;
00271 }
00272
00273
00274 template <class U, unsigned int pow2, class SearchPolicy>
00275 ChainedList<U, pow2, SearchPolicy>::~ChainedList()
00276 {
00277 Free();
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287 template <class U, unsigned int pow2, class SearchPolicy>
00288 bool ChainedList<U, pow2, SearchPolicy>::Connect(Node *pNode, Node *pP, Node *pN)
00289 {
00290 if (pNode == NULL) return false;
00291
00292 if ( pP==NULL && pN==NULL && pNode->mpuElement!=NULL && (pNode->mpxPrevious!=NULL || pNode->mpxNext!=NULL))
00293 {
00294
00295 pNode->mpxPrevious = pP;
00296 pNode->mpxNext = pN;
00297 return false;
00298 }
00299
00300 pNode->mpxPrevious = pP;
00301 pNode->mpxNext = pN;
00302
00303 return true;
00304 }
00305
00306 template <class U, unsigned int pow2, class SearchPolicy>
00307 unsigned int ChainedList<U, pow2, SearchPolicy>::indexOf(DefaultConstParamType arg)
00308 {
00309 if (mpxFirst==NULL) return ChainedEnd;
00310
00311 unsigned int i=0;
00312 Node * pNode = mpxFirst;
00313 while (i < mlNumberOfNodes && pNode!=NULL)
00314 {
00315 if (SearchPolicy::Compare(pNode->Get(), arg)) return i;
00316 i++;
00317 pNode = pNode->mpxNext;
00318 }
00319
00320 return ChainedEnd;
00321 }
00322
00323 template <class U, unsigned int pow2, class SearchPolicy>
00324 unsigned int ChainedList<U, pow2, SearchPolicy>::lastIndexOf(DefaultConstParamType arg)
00325 {
00326 if (mpxLast==NULL) return ChainedEnd;
00327
00328 unsigned int i=mlNumberOfNodes;
00329 Node * pNode = mpxLast;
00330 while (i > 0 && pNode != NULL)
00331 {
00332 if (SearchPolicy::Compare(pNode->Get(), arg)) return i - 1;
00333 i--;
00334 pNode = pNode->mpxPrevious;
00335 }
00336
00337 return ChainedEnd;
00338 }
00339
00340
00341 template <class U, unsigned int pow2, class SearchPolicy>
00342 bool ChainedList<U, pow2, SearchPolicy>::UseBlocks(const bool & arg)
00343 {
00344 if (mpxBlock != NULL) return false;
00345
00346 mbUseBlocks = arg;
00347 return true;
00348 }
00349
00350 template <class U, unsigned int pow2, class SearchPolicy>
00351 bool ChainedList<U, pow2, SearchPolicy>::Add(const ChainedList& copy, const unsigned int &pos)
00352 {
00353 if ((copy.mpxFirst==NULL)||(copy.mpxLast==NULL)) return false;
00354
00355 if (pos >= mlNumberOfNodes-1)
00356 {
00357
00358 if (mbUseBlocks)
00359 {
00360
00361 Node * pNode = NULL;
00362 Node * pNode0 = mpxLast;
00363 Node * pCopy = copy.mpxFirst;
00364
00365 for (unsigned int i=0; i < copy.mlNumberOfNodes; i++)
00366 {
00367 pNode = CreateNode();
00368 if (pNode == NULL) return false;
00369
00370 if (mpxFirst == NULL) mpxFirst = pNode;
00371 pNode->mpxPrevious = pNode0;
00372 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00373
00374 if (pCopy == NULL) return false;
00375 pNode->Set(pCopy->mpuElement);
00376 pCopy = pCopy->mpxNext;
00377 pNode0 = pNode;
00378 }
00379
00380 mlNumberOfNodes += copy.mlNumberOfNodes;
00381 mpxLast = pNode;
00382 mpxLast->mpxNext = NULL;
00383
00384 return true;
00385
00386 }
00387 else
00388 {
00389
00390
00391 Node * pNode = NULL;
00392 Node * pNode0 = mpxLast;
00393 Node * pCopy = copy.mpxFirst;
00394
00395 for (unsigned int i=0; i < copy.mlNumberOfNodes; i++)
00396 {
00397 pNode = new Node;
00398 if (pNode == NULL) return false;
00399
00400 pNode->mpxPrevious = pNode0;
00401 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00402
00403 if (pCopy == NULL) return false;
00404 pNode->Set(pCopy->mpuElement);
00405 pCopy = pCopy->mpxNext;
00406 pNode0 = pNode;
00407 }
00408
00409 mlNumberOfNodes += copy.mlNumberOfNodes;
00410 mpxLast = pNode;
00411 mpxCurrent = mpxLast;
00412 mpxLast->mpxNext = NULL;
00413
00414 return true;
00415 }
00416 }
00417 else
00418 {
00419 if (mbUseBlocks)
00420 {
00421 unsigned int i;
00422 Node * pNode = NULL;
00423 Node * pLast = mpxLast;
00424
00425
00426 for (i=0; i < copy.mlNumberOfNodes; i++)
00427 {
00428 pNode = CreateNode();
00429 if (pNode == NULL) return false;
00430
00431 pNode->mpxPrevious = pLast;
00432 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00433
00434 pLast = pNode;
00435 }
00436
00437 mlNumberOfNodes += copy.mlNumberOfNodes;
00438
00439
00440 Node * pInsert = pNode;
00441 if (pInsert == NULL) return false;
00442 Node * pFirst = Goto(pos);
00443 if (pFirst == NULL) return false;
00444
00445 pNode = mpxLast;
00446 mpxLast = pInsert;
00447 mpxLast->mpxNext = NULL;
00448
00449 for (i=pos + copy.mlNumberOfNodes; i < mlNumberOfNodes; i++)
00450 {
00451 if ((pInsert==NULL)||(pNode == NULL)) return false;
00452 pInsert->Set(pNode->mpuElement);
00453
00454 pInsert = pInsert->mpxPrevious;
00455 pNode = pNode->mpxPrevious;
00456 }
00457
00458
00459 pInsert = pFirst;
00460 pNode = copy.mpxFirst;
00461 for (i = 0; i < copy.mlNumberOfNodes; i++)
00462 {
00463 if ((pInsert==NULL)||(pNode == NULL)) return false;
00464 pInsert->Set(pNode->mpuElement);
00465
00466 pInsert = pInsert->mpxNext;
00467 pNode = pNode->mpxNext;
00468 }
00469
00470
00471 return true;
00472
00473 }
00474 else
00475 {
00476
00477 Node * pNode = NULL;
00478 Node * pFirst = Goto(pos);
00479 if (pFirst == NULL) return false;
00480 Node * pNode0 = pFirst->mpxPrevious;
00481 Node * pCopy = copy.mpxFirst;
00482
00483 for (unsigned int i=0; i < copy.mlNumberOfNodes; i++)
00484 {
00485 pNode = new Node;
00486 if (pNode == NULL) return false;
00487
00488 pNode->mpxPrevious = pNode0;
00489 if ((i==0)&&(pos==0)) mpxFirst = pNode;
00490 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00491
00492 if (pCopy == NULL) return false;
00493 pNode->Set(pCopy->mpuElement);
00494 pCopy = pCopy->mpxNext;
00495 pNode0 = pNode;
00496 }
00497
00498 mlNumberOfNodes += copy.mlNumberOfNodes;
00499 pNode->mpxNext = pFirst;
00500 pFirst->mpxPrevious = pNode;
00501
00502 return true;
00503 }
00504 }
00505
00506 }
00507
00508
00509 template <class U, unsigned int pow2, class SearchPolicy>
00510 bool ChainedList<U, pow2, SearchPolicy>::Add(U* a, const unsigned int& pos)
00511 {
00512 if (pos >= mlNumberOfNodes)
00513 {
00514
00515 if (mbUseBlocks)
00516 {
00517
00518 Node * pNode = CreateNode();
00519 if (pNode == NULL) return false;
00520
00521 pNode->Set(a);
00522 if (mpxBlock==NULL) return false;
00523 mpxBLast->soUsed ++;
00524
00525
00526 if (mlNumberOfNodes==0)
00527 mpxFirst = pNode;
00528 else
00529 mpxLast->mpxNext = pNode;
00530
00531 pNode->mpxPrevious = mpxLast;
00532 mpxLast = pNode;
00533 pNode->mpxNext = NULL;
00534 mlNumberOfNodes++;
00535
00536
00537 return true;
00538 }
00539 else
00540 {
00541 if (mpxFirst==NULL)
00542 {
00543
00544 mpxFirst = new Node(a);
00545
00546
00547 if (mpxFirst == NULL) return false;
00548
00549
00550 if (!Connect(mpxFirst,NULL,NULL)) return false;
00551
00552
00553 mpxLast = mpxFirst;
00554 mpxCurrent = mpxFirst;
00555
00556
00557 mlNumberOfNodes = 1;
00558
00559
00560 return true;
00561 }
00562 else
00563 {
00564
00565 mpxCurrent = new Node(a);
00566
00567
00568 if (mpxCurrent == NULL) return false;
00569
00570
00571 if (!Connect(mpxCurrent,mpxLast,NULL)) return false;
00572 mpxLast->mpxNext = mpxCurrent;
00573 mpxLast = mpxCurrent;
00574
00575
00576 mlNumberOfNodes ++;
00577
00578
00579 return true;
00580
00581 }
00582 }
00583 }
00584 else
00585 {
00586
00587
00588
00589 if (mbUseBlocks)
00590 {
00591
00592 Node * pNode;
00593
00594
00595 if (mpxBlock==NULL)
00596 { if (pos == 0) return Add(a); else return false; }
00597
00598 LinearBlock<ChainedBS> * pBlock = mpxBLast;
00599
00600 if (pBlock->soUsed < ChainedBS)
00601 {
00602
00603
00604
00605 if (mpxCurrent->mpxPrevious == NULL || mpxCurrent->mpxPrevious->mpxNext == mpxCurrent || mpxCurrent->mpxNext == NULL)
00606 {
00607
00608 if (mpxLast != NULL && mpxLast >= &pBlock->sapxBlock[0] && mpxLast < &pBlock->sapxBlock[ChainedBS - 1])
00609 mpxCurrent = (mpxLast + 1);
00610 }
00611 if (mpxCurrent == NULL) return false;
00612
00613 mpxLast->mpxNext = mpxCurrent;
00614 mpxLast = mpxCurrent;
00615 mpxCurrent = mpxCurrent->mpxNext;
00616 mpxLast->mpxNext = NULL;
00617 pNode = mpxLast;
00618
00619
00620 for (unsigned int i=pos; i < mlNumberOfNodes; i++)
00621 {
00622 if (pNode->mpxPrevious !=NULL)
00623 {
00624 pNode->Set(pNode->mpxPrevious->mpuElement);
00625 pNode = pNode->mpxPrevious;
00626 }
00627 }
00628
00629
00630 pNode->Set(a);
00631
00632 pBlock->soUsed++;
00633 mlNumberOfNodes ++;
00634 return true;
00635 }
00636 else
00637 {
00638 unsigned int i;
00639
00640 if (!pBlock->CreateNewBlock()) return false;
00641
00642 pBlock = pBlock->spxNext;
00643 mpxBLast = pBlock;
00644
00645
00646 pNode = pBlock->GetData();
00647
00648
00649 mpxCurrent = mpxLast;
00650 for (i = 0; i < ChainedBS; i++, pNode++)
00651 {
00652 pNode->mpxPrevious = mpxCurrent;
00653
00654
00655
00656 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00657 mpxCurrent = pNode;
00658 }
00659
00660 mlNumberOfBlocks ++;
00661 mpxCurrent -= ChainedBS - 1;
00662
00663
00664
00665 if (mpxCurrent == NULL) return false;
00666
00667 mpxLast->mpxNext = mpxCurrent;
00668 mpxLast = mpxCurrent;
00669 mpxCurrent = mpxCurrent->mpxNext;
00670 mpxLast->mpxNext = NULL;
00671 pNode = mpxLast;
00672
00673
00674 for (i=pos; i < mlNumberOfNodes; i++)
00675 {
00676 if (pNode->mpxPrevious !=NULL)
00677 {
00678 pNode->Set(pNode->mpxPrevious->mpuElement);
00679 pNode = pNode->mpxPrevious;
00680 }
00681
00682
00683 }
00684
00685
00686 pNode->Set(a);
00687
00688 pBlock->soUsed++;
00689 mlNumberOfNodes ++;
00690 return true;
00691
00692 }
00693
00694 }
00695 else
00696 {
00697
00698 Node * pNode = new Node(a);
00699
00700
00701 if (pos!=0)
00702 {
00703 mpxCurrent = Goto(pos-1);
00704 if (mpxCurrent == NULL) return false;
00705
00706 Connect(pNode, mpxCurrent, mpxCurrent->mpxNext);
00707 mpxCurrent->mpxNext = pNode;
00708 if (pNode->mpxNext!=NULL) pNode->mpxNext->mpxPrevious = pNode;
00709 } else
00710 {
00711
00712 Connect(pNode, NULL, mpxFirst);
00713 mpxFirst->mpxPrevious = pNode;
00714 mpxFirst = pNode;
00715
00716 }
00717
00718
00719 mlNumberOfNodes ++;
00720 }
00721 return true;
00722 }
00723 }
00724
00725 template <class U, unsigned int pow2, class SearchPolicy>
00726 bool ChainedList<U, pow2, SearchPolicy>::Sub(const unsigned int& pos)
00727 {
00728 if (pos >= mlNumberOfNodes-1)
00729 {
00730
00731 if (mbUseBlocks)
00732 {
00733
00734 if ((mpxLast == NULL)||(mpxBlock == NULL)) return false;
00735
00736 LinearBlock<ChainedBS> * pBlock = mpxBLast;
00737 Node * pNode = mpxLast->mpxPrevious;
00738
00739 if (pNode==NULL)
00740 {
00741
00742 if (!mpxBlock->DeleteAll()) return false;
00743 mpxBlock = NULL;
00744 mpxBLast = NULL;
00745 mlNumberOfNodes = 0;
00746 mlNumberOfBlocks = 0;
00747 mbUseBlocks = true;
00748 mbIntegrity = true;
00749 mpxCurrent = mpxFirst = mpxLast = NULL;
00750 return true;
00751 }
00752
00753 if (pBlock->soUsed == 1)
00754 {
00755
00756 pNode->mpxNext = NULL;
00757 mpxLast = pNode;
00758 mpxCurrent = NULL;
00759 pBlock->soUsed = 0;
00760 mlNumberOfNodes --;
00761 mlNumberOfBlocks --;
00762 mpxBLast = pBlock->spxPrevious;
00763 pBlock->Delete();
00764
00765 return true;
00766 }
00767
00768
00769 pNode->mpxNext = NULL;
00770 mpxLast->mpxNext = mpxCurrent;
00771 mpxCurrent = mpxLast;
00772 mpxLast = pNode;
00773
00774 mlNumberOfNodes --;
00775 pBlock->soUsed --;
00776
00777 return true;
00778
00779
00780 }
00781 else
00782 {
00783 if (mpxLast == NULL) return false;
00784 Node * pNode = mpxLast->mpxPrevious;
00785
00786 if (pNode == NULL)
00787 {
00788
00789 delete mpxLast;
00790 mpxLast = mpxFirst = mpxCurrent = NULL;
00791 mlNumberOfNodes = 0;
00792 return true;
00793 }
00794
00795 pNode->mpxNext = NULL;
00796 delete mpxLast;
00797 mpxLast = pNode;
00798 mpxCurrent = mpxLast;
00799 mlNumberOfNodes --;
00800
00801 return true;
00802 }
00803 }
00804 else
00805 {
00806
00807 if (mbUseBlocks)
00808 {
00809
00810 if ((mpxLast == NULL)||(mpxBlock == NULL)) return false;
00811
00812 LinearBlock<ChainedBS> * pBlock = mpxBLast;
00813 Node * pNode = Goto(pos);
00814
00815 if ((pNode == NULL)||(pBlock==NULL)) return false;
00816
00817
00818 delete pNode->mpuElement;
00819 pNode->mpuElement = NULL;
00820
00821 if (pBlock->soUsed == 1)
00822 {
00823
00824 for (unsigned int i = pos+1; i < mlNumberOfNodes; i++)
00825 {
00826 if (pNode->mpxNext == NULL) return false;
00827 pNode->Set(pNode->mpxNext->mpuElement);
00828 pNode = pNode->mpxNext;
00829 }
00830
00831
00832 mpxCurrent = NULL;
00833
00834 mpxLast = mpxLast->mpxPrevious;
00835 mpxLast->mpxNext = NULL;
00836
00837 pBlock->soUsed = 0;
00838 mpxBLast = pBlock->spxPrevious;
00839 pBlock->Delete();
00840
00841 mlNumberOfNodes --;
00842 mlNumberOfBlocks --;
00843
00844 return true;
00845 }
00846
00847
00848 for (unsigned int i = pos+1; i < mlNumberOfNodes; i++)
00849 {
00850 if (pNode->mpxNext == NULL) return false;
00851 pNode->Set(pNode->mpxNext->mpuElement);
00852 pNode = pNode->mpxNext;
00853 }
00854
00855
00856 mpxLast->mpxNext = mpxCurrent;
00857
00858 mpxCurrent = mpxLast;
00859
00860 mpxLast = mpxLast->mpxPrevious;
00861 mpxLast->mpxNext = NULL;
00862
00863 mpxCurrent->Set((U*)NULL);
00864
00865 pBlock->soUsed --;
00866
00867 mlNumberOfNodes --;
00868
00869 return true;
00870
00871
00872 }
00873 else
00874 {
00875
00876 Node * pNode = Goto(pos);
00877 if (pNode == NULL) return false;
00878
00879
00880 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode->mpxNext;
00881 if (pNode->mpxNext!=NULL) pNode->mpxNext->mpxPrevious = pNode->mpxPrevious;
00882
00883
00884 if (pNode == mpxFirst) mpxFirst = pNode->mpxNext;
00885
00886 if (pNode == mpxLast) mpxLast = pNode->mpxPrevious;
00887
00888
00889 delete pNode;
00890 mlNumberOfNodes --;
00891
00892 return true;
00893 }
00894
00895 }
00896 }
00897
00898 template <class U, unsigned int pow2, class SearchPolicy>
00899 bool ChainedList<U, pow2, SearchPolicy>::Insert(DefaultConstParamType a, const unsigned int& pos)
00900 {
00901 if (pos>= mlNumberOfNodes) return Add(a);
00902
00903 Node * pNode;
00904 if (mbUseBlocks)
00905 {
00906
00907 pNode = CreateNode();
00908
00909
00910 mbIntegrity = false;
00911 }
00912 else
00913 {
00914 pNode = new Node(a);
00915 }
00916
00917 if (pNode == NULL) return false;
00918
00919 pNode->Set(a);
00920
00921
00922 pNode->mpxNext = Goto(pos);
00923 if (pNode->mpxNext==NULL) return false;
00924
00925 pNode->mpxPrevious = pNode->mpxNext->mpxPrevious;
00926 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
00927 pNode->mpxNext->mpxPrevious = pNode;
00928
00929 return true;
00930 }
00931
00932 template <class U, unsigned int pow2, class SearchPolicy>
00933 bool ChainedList<U, pow2, SearchPolicy>::Swap(const unsigned int& pos0, const unsigned int& pos1)
00934 {
00935 if ( pos0>= mlNumberOfNodes || pos1>= mlNumberOfNodes) return false;
00936
00937
00938 Node * pNode0 = Goto(pos0);
00939 Node * pNode1 = Goto(pos1);
00940
00941 if ((pNode0==NULL)||(pNode1==NULL)) return false;
00942
00943 if (mbUseBlocks)
00944 {
00945
00946
00947
00948 U * a = pNode1->mpuElement;
00949 pNode1->Set(pNode0->mpuElement);
00950 pNode0->Set(a);
00951
00952 return true;
00953 }
00954 else
00955 {
00956 if ((pNode0->mpxNext == pNode1)||(pNode0->mpxPrevious == pNode1))
00957 {
00958
00959 if (pNode0->mpxNext == pNode1)
00960 {
00961
00962 if (pNode0->mpxPrevious!=NULL) pNode0->mpxPrevious->mpxNext = pNode1;
00963 if (pNode1->mpxNext!=NULL) pNode1->mpxNext->mpxPrevious = pNode0;
00964
00965 pNode0->mpxNext = pNode1->mpxNext;
00966 pNode1->mpxPrevious = pNode0->mpxPrevious;
00967 pNode0->mpxPrevious = pNode1;
00968 pNode1->mpxNext = pNode0;
00969 } else
00970 {
00971
00972 if (pNode1->mpxPrevious!=NULL) pNode1->mpxPrevious->mpxNext = pNode0;
00973 if (pNode0->mpxNext!=NULL) pNode0->mpxNext->mpxPrevious = pNode1;
00974
00975 pNode1->mpxNext = pNode0->mpxNext;
00976 pNode0->mpxPrevious = pNode1->mpxPrevious;
00977 pNode1->mpxPrevious = pNode0;
00978 pNode0->mpxNext = pNode1;
00979 }
00980
00981 return true;
00982 }
00983
00984
00985 Node * pNodeTemp0 = pNode0->mpxPrevious;
00986 Node * pNodeTemp1 = pNode0->mpxNext;
00987
00988 if (pNode0->mpxPrevious!=NULL) pNode0->mpxPrevious->mpxNext = pNode1;
00989 if (pNode0->mpxNext!=NULL) pNode0->mpxNext->mpxPrevious = pNode1;
00990 if (pNode1->mpxPrevious!=NULL) pNode1->mpxPrevious->mpxNext = pNode0;
00991 if (pNode1->mpxNext!=NULL) pNode1->mpxNext->mpxPrevious = pNode0;
00992
00993 pNode0->mpxPrevious = pNode1->mpxPrevious;
00994 pNode0->mpxNext = pNode1->mpxNext;
00995
00996 pNode1->mpxPrevious = pNodeTemp0;
00997 pNode1->mpxNext = pNodeTemp1;
00998
00999 if (pNode0 == mpxLast) mpxLast = pNode1;
01000 if (pNode1 == mpxLast) mpxLast = pNode0;
01001 if (pNode0 == mpxFirst) mpxFirst = pNode1;
01002 if (pNode1 == mpxFirst) mpxFirst = pNode0;
01003
01004 return true;
01005 }
01006 }
01007
01008 template <class U, unsigned int pow2, class SearchPolicy>
01009 bool ChainedList<U, pow2, SearchPolicy>::Remove(const unsigned int& pos)
01010 {
01011 if (pos>= mlNumberOfNodes) return false;
01012
01013
01014 Node * pNode = Goto(pos);
01015 if (pNode == NULL) return false;
01016
01017 if (mbUseBlocks)
01018 {
01019
01020 if (pNode==mpxLast)
01021 {
01022 LinearBlock<ChainedBS> * pBlock = mpxBLast;
01023 if (pBlock == NULL) return false;
01024 if (pBlock->soUsed == 1)
01025 {
01026
01027 pNode = mpxLast->mpxPrevious;
01028 if (pNode != NULL) pNode->mpxNext = NULL;
01029 mpxLast = pNode;
01030 mpxCurrent = NULL;
01031
01032
01033 pBlock->soUsed = 0;
01034 mlNumberOfNodes --;
01035 mlNumberOfBlocks --;
01036 mpxBLast = pBlock->spxPrevious;
01037 pBlock->Delete();
01038
01039 if (!mlNumberOfBlocks) mpxBlock = NULL;
01040 if (!mlNumberOfNodes) mpxFirst = NULL;
01041 }
01042 else
01043 {
01044 mpxLast->mpxNext = mpxCurrent;
01045 mpxCurrent = mpxLast;
01046 mpxLast = mpxLast->mpxPrevious;
01047 mpxLast->mpxNext= NULL;
01048
01049 mlNumberOfNodes --;
01050 pBlock->soUsed --;
01051
01052 }
01053 delete pNode->mpuElement;
01054 pNode->Set((U*)NULL);
01055 return true;
01056 }
01057
01058
01059 LinearBlock<ChainedBS> * pBlock = mpxBlock->Find(pNode);
01060 if (pBlock == NULL) return false;
01061 pBlock->soUsed --;
01062
01063 mbIntegrity = false;
01064
01065 }
01066
01067
01068 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode->mpxNext;
01069 if (pNode->mpxNext!=NULL) pNode->mpxNext->mpxPrevious = pNode->mpxPrevious;
01070
01071
01072 if (pNode == mpxFirst) mpxFirst = pNode->mpxNext;
01073
01074 if (pNode == mpxLast) mpxLast = pNode->mpxPrevious;
01075
01076
01077 if (!mbUseBlocks) delete pNode; else { delete pNode->mpuElement; pNode->Set((U*)NULL); }
01078 mlNumberOfNodes --;
01079
01080 return true;
01081 }
01082
01083 template <class U, unsigned int pow2, class SearchPolicy>
01084 typename ChainedList<U, pow2, SearchPolicy>::Node* ChainedList<U, pow2, SearchPolicy>::CreateNode()
01085 {
01086 if (mpxCurrent == NULL)
01087 {
01088
01089
01090 LinearBlock<ChainedBS> * pBlock;
01091 if (mpxBlock == NULL)
01092 {
01093 mpxBlock = new LinearBlock<ChainedBS>;
01094 if (mpxBlock==NULL) return NULL;
01095 mpxBLast = mpxBlock;
01096 pBlock = mpxBlock;
01097 }
01098 else
01099 {
01100
01101 if (mpxBlock->soUsed < ChainedBS)
01102 {
01103
01104
01105
01106 Node * pNode = mpxBlock->GetData();
01107 for (unsigned int i = 0; i < ChainedBS; i++)
01108 {
01109 if (pNode == NULL) return NULL;
01110 if (pNode->mpxNext != (pNode+1))
01111 {
01112
01113 return (pNode+1);
01114 }
01115
01116 pNode ++;
01117 }
01118 return NULL;
01119 }
01120
01121 pBlock = mpxBLast;
01122 if (pBlock->CreateNewBlock()!=true) return NULL;
01123 pBlock = pBlock->spxNext;
01124 mpxBLast = pBlock;
01125 }
01126
01127
01128
01129 Node * pNode = (Node*) pBlock->GetData();
01130
01131
01132
01133 for (unsigned int i = 0; i < ChainedBS; i++, pNode++)
01134 {
01135 pNode->mpxPrevious = mpxCurrent;
01136
01137
01138
01139 if (pNode->mpxPrevious!=NULL) pNode->mpxPrevious->mpxNext = pNode;
01140 mpxCurrent = pNode;
01141 }
01142
01143 mpxCurrent -= ChainedBS - 1;
01144
01145
01146 mlNumberOfBlocks ++;
01147
01148 mpxCurrent = mpxCurrent->mpxNext;
01149 return mpxCurrent->mpxPrevious;
01150
01151 }
01152
01153 if (mpxCurrent==NULL) return NULL;
01154
01155
01156 if (mpxCurrent->mpxPrevious == NULL || mpxCurrent->mpxPrevious->mpxNext == mpxCurrent || mpxCurrent->mpxNext == NULL)
01157 {
01158
01159 if (mpxBLast != NULL && mpxBLast->soUsed < ChainedBS)
01160 {
01161
01162 Node * pNode = mpxBLast->GetData();
01163 for (unsigned int i = 0; i < ChainedBS; i++)
01164 {
01165 if (pNode == NULL) return NULL;
01166 if (pNode->mpxNext != (pNode+1))
01167 {
01168
01169
01170
01171 if ((pNode+1) > (mpxBLast->GetData() + ChainedBS))
01172 {
01173
01174 mpxCurrent = NULL;
01175 return CreateNode();
01176 }
01177 else
01178
01179 {
01180 mpxCurrent = (pNode + 1)->mpxNext;
01181 }
01182
01183 return (pNode+1);
01184 }
01185 pNode ++;
01186 }
01187 }
01188
01189 else
01190 {
01191 mpxCurrent = NULL;
01192 return CreateNode();
01193 }
01194 }
01195
01196 mpxCurrent = mpxCurrent->mpxNext;
01197
01198 return mpxCurrent->mpxPrevious;
01199 }
01200
01201
01202
01203 template <class U, unsigned int pow2, class SearchPolicy>
01204 typename ChainedList<U, pow2, SearchPolicy>::Node* ChainedList<U, pow2, SearchPolicy>::Goto(const unsigned int& pos)
01205 {
01206 if (mpxFirst == NULL) return NULL;
01207
01208 Node* pT;
01209 if ( mbUseBlocks && mbIntegrity )
01210 {
01211 if (mpxBlock==NULL) return NULL;
01212
01213 unsigned int distinblock = (pos>>pow2);
01214 LinearBlock<ChainedBS> *pBlock = mpxBlock;
01215
01216
01217 for (unsigned int i = 0; i < distinblock; i++)
01218 {
01219 if (pBlock==NULL) return NULL;
01220 pBlock = pBlock->spxNext;
01221 }
01222
01223 pT = pBlock->GetData();
01224 pT += pos - (distinblock<<pow2);
01225
01226 }
01227 else
01228 {
01229 if (pos <= (mlNumberOfNodes>>1))
01230 {
01231
01232 pT = mpxFirst;
01233
01234 for (unsigned int i=0; i<pos; i++)
01235 {
01236 if (pT==NULL) return NULL;
01237 pT = pT->mpxNext;
01238 }
01239 } else
01240 {
01241
01242 pT = mpxLast;
01243
01244 for (unsigned int i=pos+1; i < mlNumberOfNodes; i++)
01245 {
01246 if (pT==NULL) return NULL;
01247 pT = pT->mpxPrevious;
01248 }
01249
01250 }
01251 }
01252 return pT;
01253 }
01254
01255 template <class U, unsigned int pow2, class SearchPolicy>
01256 bool ChainedList<U, pow2, SearchPolicy>::Change(DefaultConstParamType a, const unsigned int & pos)
01257 {
01258 if (mpxFirst == NULL) return false;
01259
01260 if (pos > mlNumberOfNodes) return false;
01261
01262 if (pos == mlNumberOfNodes) Add(a);
01263
01264 Node* pT = Goto(pos);
01265 if (pT == NULL) return false;
01266
01267 if (pT->mpuElement != NULL)
01268 delete pT->mpuElement;
01269
01270 pT->Set(a);
01271
01272 return true;
01273
01274 }
01275
01276
01277 template <class U, unsigned int pow2, class SearchPolicy>
01278 bool ChainedList<U, pow2, SearchPolicy>::Free()
01279 {
01280 if (mpxFirst == NULL) return false;
01281
01282 if (mbUseBlocks)
01283 {
01284 if (mpxBlock == NULL) return false;
01285
01286 mpxBlock->DeleteAll();
01287 mpxBlock = NULL;
01288 mpxFirst = mpxLast = mpxCurrent = NULL;
01289 mlNumberOfNodes = 0;
01290 mlNumberOfBlocks = 0;
01291 mbIntegrity = true;
01292 mbUseBlocks = true;
01293
01294 }
01295 else
01296 {
01297 mpxCurrent = mpxFirst;
01298 for (unsigned int i=0; i < mlNumberOfNodes; i++)
01299 {
01300 if (mpxCurrent == NULL) return false;
01301 mpxLast = mpxCurrent->mpxNext;
01302 delete mpxCurrent;
01303
01304 mpxCurrent = mpxLast;
01305 }
01306
01307 mpxFirst = mpxLast = mpxCurrent = NULL;
01308 mlNumberOfNodes = 0;
01309 mbIntegrity = true;
01310 }
01311
01312 return true;
01313 }
01314
01315 template <class U, unsigned int pow2, class SearchPolicy>
01316 U* ChainedList<U, pow2, SearchPolicy>::parseList(const bool & bInit) const
01317 {
01318 if (mpxFirst == NULL) return NULL;
01319
01320 if (bInit) { mpxCurrent = mpxFirst; return mpxCurrent->mpuElement; }
01321 else if (mpxCurrent!=mpxLast) { mpxCurrent = mpxCurrent->mpxNext; return mpxCurrent->mpuElement; }
01322 else return NULL;
01323 }
01324
01325 template <class U, unsigned int pow2, class SearchPolicy>
01326 U* ChainedList<U, pow2, SearchPolicy>::parseListStart(const unsigned int & uiPos) const
01327 {
01328 if (uiPos != ChainedEnd) { mpxCurrent = Goto(uiPos); if (mpxCurrent!=NULL) return mpxCurrent->mpuElement; else return NULL; }
01329 else if (mpxCurrent!=NULL) { mpxCurrent = mpxCurrent->mpxNext; return mpxCurrent->mpuElement; }
01330 else return NULL;
01331 }
01332
01333 template <class U, unsigned int pow2, class SearchPolicy>
01334 U* ChainedList<U, pow2, SearchPolicy>::reverseParseList(const bool & bInit) const
01335 {
01336 if (mpxLast == NULL) return NULL;
01337
01338 if (bInit) { mpxCurrent = mpxLast; return mpxCurrent->mpuElement; }
01339 else if (mpxCurrent!=mpxFirst) { mpxCurrent = mpxCurrent->mpxPrevious; return mpxCurrent->mpuElement; }
01340 else return NULL;
01341 }
01342
01343 template <class U, unsigned int pow2, class SearchPolicy>
01344 U* ChainedList<U, pow2, SearchPolicy>::reverseParseListStart(const unsigned int & uiPos) const
01345 {
01346 if (uiPos != ChainedEnd) { mpxCurrent = Goto(uiPos); if (mpxCurrent!=NULL) return mpxCurrent->mpuElement; else return NULL; }
01347 else if (mpxCurrent!=NULL) { mpxCurrent = mpxCurrent->mpxPrevious; return mpxCurrent->mpuElement; }
01348 else return NULL;
01349 }
01350
01351
01352
01353
01354