00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "C_MultiList.hpp"
00039 #include "Utils.hpp"
00040
00041 #include "iostream_t.hpp"
00042 #ifdef GEN_DEBUG_MULTILIST
00043 #define MLIST_GEN_DEBUG(m) iostream_error << m << iostream_flush << iostream_endl
00044 #define MLIST_GEN_FATAL(m) iostream_error << m << iostream_flush << iostream_endl
00045 #else
00046 #define MLIST_GEN_DEBUG(m)
00047 #define MLIST_GEN_FATAL(m)
00048 #endif
00049
00050
00051 #include <cassert>
00052
00053
00054
00055 template <class Type> int C_MultiList<Type>::removeElement ( long elementIdx )
00056 {
00057 int L_return = TST_OK ;
00058 long L_oldState ;
00059 long L_prev;
00060 long L_next;
00061
00062 #ifdef GEN_DEBUG_MULTILIST
00063 if ( ! initDone )
00064 {
00065 MLIST_GEN_FATAL("initList has NOT been called before using list");
00066 assert (0);
00067 }
00068 MLIST_GEN_DEBUG("BEGIN removeElement, element=" << elementIdx << ", state=" << elementList[elementIdx].currentList);
00069 #endif
00070
00071
00072 L_prev = elementList[elementIdx].prevElement ;
00073 L_next = elementList[elementIdx].nextElement ;
00074
00075
00076 L_oldState = elementList[elementIdx].currentList ;
00077
00078
00079
00080
00081
00082
00083
00084
00085 if ( stateList[L_oldState].firstElement == elementIdx )
00086 {
00087 if ( stateList[L_oldState].lastElement == elementIdx )
00088 {
00089
00090
00091 stateList[L_oldState].firstElement = NULL_INDEX_ELEMENT ;
00092 stateList[L_oldState].lastElement = NULL_INDEX_ELEMENT ;
00093 }
00094 else
00095 {
00096
00097
00098 stateList[L_oldState].firstElement = L_next ;
00099
00100
00101 elementList[L_next].prevElement = NULL_INDEX_ELEMENT ;
00102 }
00103 }
00104 else
00105 {
00106 if ( stateList[L_oldState].lastElement == elementIdx )
00107 {
00108
00109
00110 stateList[L_oldState].lastElement = L_prev ;
00111
00112
00113 elementList[L_prev].nextElement = NULL_INDEX_ELEMENT ;
00114 }
00115 else
00116 {
00117
00118 elementList[L_next].prevElement = L_prev ;
00119 elementList[L_prev].nextElement = L_next ;
00120 }
00121 }
00122
00123 #ifdef GEN_DEBUG_MULTILIST
00124 MLIST_GEN_DEBUG ("END removeElement, FirstIdle=" << stateList[L_oldState].firstElement
00125 << ", LastIdle=" << stateList[L_oldState].lastElement);
00126
00127 #endif
00128
00129 return ( L_return );
00130 }
00131
00132 template <class Type> int C_MultiList<Type>::initSingleElement( long P_initState , long elementIdx )
00133 {
00134 int L_return = TST_OK ;
00135
00136 elementList[elementIdx].currentList = P_initState ;
00137
00138 if ( elementIdx != 0 )
00139 {
00140 elementList[elementIdx].prevElement = elementIdx-1 ;
00141 }
00142 else
00143 {
00144 elementList[elementIdx].prevElement = NULL_INDEX_ELEMENT ;
00145 }
00146
00147 if ( elementIdx != nbElements-1 )
00148 {
00149 elementList[elementIdx].nextElement = elementIdx+1 ;
00150 }
00151 else
00152 {
00153 elementList[elementIdx].nextElement = NULL_INDEX_ELEMENT ;
00154 }
00155
00156 elementList[elementIdx].payLoad = NULL;
00157
00158 return (L_return) ;
00159 }
00160
00161
00162
00163 template <class Type> C_MultiList<Type>::C_MultiList ( long numberOfLists, long numberOfElements )
00164 {
00165
00166 firstListIndex = 0;
00167 lastListIndex = numberOfLists - 1;
00168 nbLists = numberOfLists;
00169 nbElements = numberOfElements;
00170
00171 ALLOC_TABLE (elementList, struct_element*,
00172 sizeof(struct_element), numberOfElements) ;
00173 ALLOC_TABLE (stateList, struct_listHeader*,
00174 sizeof(struct_listHeader), numberOfLists) ;
00175
00176 initDone = 0;
00177
00178 if (!elementList || !stateList )
00179 {
00180 iostream_error
00181 << "C_MultiList class constructor : cannot allocate required memory ("
00182 << numberOfLists << " lists and "
00183 << numberOfElements<< " elements )" << iostream_endl << iostream_flush ;
00184 assert (0);
00185 }
00186 };
00187
00188 template <class Type> C_MultiList<Type>::~C_MultiList ( void )
00189 {
00190 #ifdef GEN_DEBUG_MULTILIST
00191 MLIST_GEN_DEBUG("C_MultiList destructor " << nbLists << " lists and " << nbElements << " elements ");
00192 #endif
00193
00194 FREE_TABLE (elementList);
00195 FREE_TABLE (stateList);
00196 };
00197
00198 template <class Type> int C_MultiList<Type>::initList (long P_initState)
00199 {
00200 int L_return = TST_OK ;
00201 long elementIdx = 0 ;
00202 long listIndex = 0;
00203
00204
00205 if (P_initState >= firstListIndex && P_initState <= lastListIndex )
00206 {
00207
00208
00209 for ( listIndex = 0 ; listIndex < nbLists ; listIndex ++ )
00210 {
00211 stateList[ listIndex ].firstElement = NULL_INDEX_ELEMENT ;
00212 stateList[ listIndex ].lastElement = NULL_INDEX_ELEMENT ;
00213 stateList[ listIndex ].nbElements = 0;
00214 }
00215
00216 stateList[P_initState].firstElement = 0 ;
00217 stateList[P_initState].lastElement = nbElements - 1;
00218 stateList[P_initState].nbElements = nbElements;
00219
00220
00221 elementIdx = 0 ;
00222 while ( ( L_return == TST_OK ) && ( elementIdx < nbElements ) )
00223 {
00224
00225 L_return = initSingleElement( P_initState , elementIdx ) ;
00226 elementIdx ++ ;
00227 }
00228
00229 initDone = 1;
00230 }
00231 else
00232 {
00233 iostream_error << "GEN_ERROR : initList : P_initState="
00234 << P_initState << iostream_endl ;
00235 L_return = TST_ERROR;
00236 }
00237
00238 return (L_return) ;
00239
00240 };
00241
00242 template <class Type> int C_MultiList<Type>::moveToList (long listIdx, long elementIdx)
00243 {
00244 int L_return = TST_OK ;
00245 long prevElemList;
00246
00247 #ifdef GEN_DEBUG_MULTILIST
00248 if ( ! initDone )
00249 {
00250 MLIST_GEN_FATAL("initList has NOT been called before using list");
00251 assert (0);
00252 }
00253 MLIST_GEN_DEBUG ("BEGIN C_MultiList::moveToList ( element " << elementIdx << " list " << listIdx << " )");
00254 #endif
00255
00256 #ifdef MLIST_ARGUMENTS_TESTING
00257
00258 if (listIdx >= firstListIndex && listIdx <= lastListIndex && elementIdx != TST_ERROR )
00259 {
00260 #endif
00261
00262
00263 prevElemList = elementList[elementIdx].currentList;
00264
00265
00266 L_return = removeElement ( elementIdx ) ;
00267
00268
00269 if ( stateList[listIdx].lastElement == NULL_INDEX_ELEMENT )
00270 {
00271
00272 elementList[elementIdx].prevElement = NULL_INDEX_ELEMENT ;
00273 elementList[elementIdx].nextElement = NULL_INDEX_ELEMENT ;
00274 stateList[listIdx].firstElement = elementIdx ;
00275 stateList[listIdx].lastElement = elementIdx ;
00276 }
00277 else
00278 {
00279
00280
00281
00282
00283
00284 elementList[stateList[listIdx].lastElement].nextElement = elementIdx ;
00285 elementList[elementIdx].prevElement = stateList[listIdx].lastElement ;
00286 elementList[elementIdx].nextElement = NULL_INDEX_ELEMENT ;
00287 stateList[listIdx].lastElement = elementIdx ;
00288 }
00289
00290
00291
00292 stateList[prevElemList].nbElements --;
00293
00294
00295 stateList[listIdx].nbElements ++;
00296
00297
00298 elementList[elementIdx].currentList = listIdx ;
00299
00300 #ifdef MLIST_ARGUMENTS_TESTING
00301 }
00302 else
00303 {
00304 MLIST_GEN_DEBUG ("C_MultiList::moveToList : out of bounds arguments : list " << listIdx << " element " << elementIdx);
00305 assert (0);
00306 L_return = TST_ERROR;
00307 }
00308 #endif
00309
00310
00311 #ifdef MLIST_INTERNAL_COHERENCE
00312
00313 long prevE = -1;
00314 long nextE = -1;
00315
00316 prevE = elementList[elementIdx].nextElement;
00317 nextE = elementList[elementIdx].prevElement;
00318
00319 if ( nextE != -1 )
00320 {
00321 if ( elementList[elementIdx].currentList != elementList[nextE].currentList )
00322 {
00323 MLIST_GEN_FATAL ("C_MultiList::moveToList: next element list is not the same as current elem list!!! ");
00324 assert (0);
00325 }
00326 }
00327
00328 if ( prevE != -1 )
00329 {
00330 if ( elementList[elementIdx].currentList != elementList[prevE].currentList )
00331 {
00332 MLIST_GEN_FATAL ("C_MultiList::moveToList: prev element list is not the same as current elem list!!! ");
00333 assert (0);
00334 }
00335 }
00336
00337
00338 #endif
00339 return ( L_return );
00340 };
00341
00342 template <class Type> long C_MultiList<Type>::getFirst (long listIdx)
00343 {
00344 #ifdef GEN_DEBUG_MULTILIST
00345 MLIST_GEN_DEBUG("BEGIN getFirst " << listIdx);
00346 #endif
00347
00348 #ifdef MLIST_ARGUMENTS_TESTING
00349 if (listIdx >= firstListIndex && listIdx <= lastListIndex)
00350 {
00351 # ifdef GEN_DEBUG_MULTILIST
00352 MLIST_GEN_DEBUG("END getFirst : returning " << stateList[listIdx].firstElement );
00353 # endif
00354 #endif
00355 return ( stateList[listIdx].firstElement );
00356 #ifdef MLIST_ARGUMENTS_TESTING
00357 }
00358 else
00359 {
00360 MLIST_GEN_DEBUG ("END getFirst : out of bounds list index (" << listIdx << " while max index is " << lastListIndex << ")");
00361 assert (0);
00362 return (TST_ERROR);
00363 }
00364 #endif
00365 };
00366
00367 template <class Type> long C_MultiList<Type>::getNext (long elementIndex)
00368 {
00369 #ifdef GEN_DEBUG_MULTILIST
00370 MLIST_GEN_DEBUG("BEGIN getNext of element " << elementIndex);
00371 #endif
00372
00373 #ifdef MLIST_ARGUMENTS_TESTING
00374 if (elementIndex >= 0 && elementIndex < nbElements)
00375 {
00376 # ifdef GEN_DEBUG_MULTILIST
00377 MLIST_GEN_DEBUG("END getNext : returning " << elementList[elementIndex].nextElement);
00378 # endif
00379 #endif
00380 return ( elementList[elementIndex].nextElement );
00381
00382 #ifdef MLIST_ARGUMENTS_TESTING
00383 }
00384 else
00385 {
00386 MLIST_GEN_DEBUG ("C_MultiList::getNext : out of bounds index ( " << elementIndex << " )");
00387 assert (0);
00388 return (TST_ERROR);
00389 }
00390 #endif
00391 };
00392
00393 template <class Type> int C_MultiList<Type>::isInState (long listIdx, long elementIndex)
00394 {
00395 #ifdef MLIST_ARGUMENTS_TESTING
00396 if (listIdx >= firstListIndex && listIdx <= lastListIndex && elementIndex >= 0 && elementIndex < nbElements )
00397 {
00398 #endif
00399 return ( elementList[elementIndex].currentList == listIdx )
00400 ? 1 : 0 ;
00401 #ifdef MLIST_ARGUMENTS_TESTING
00402 }
00403 else
00404 {
00405 MLIST_GEN_DEBUG ("GEN_ERROR : isInState : out of bound indexes. Returning TST_ERROR, BEWARE.");
00406 return (TST_ERROR);
00407 }
00408 #endif
00409 };
00410
00411 template <class Type> long C_MultiList<Type>::getCurrentList (long elementIndex)
00412 {
00413 #ifdef MLIST_ARGUMENTS_TESTING
00414 if (elementIndex >= 0 && elementIndex < nbElements )
00415 {
00416 #endif
00417
00418 return ( elementList[elementIndex].currentList);
00419
00420 #ifdef MLIST_ARGUMENTS_TESTING
00421 }
00422 else
00423 {
00424 MLIST_GEN_DEBUG("GEN_ERROR : isInState : out of bound indexes. Returning TST_ERROR, BEWARE.");
00425 return (TST_ERROR);
00426 }
00427 #endif
00428 }
00429
00430 template <class Type> Type * C_MultiList<Type>::getElementPayload ( long elementIndex)
00431 {
00432
00433 #ifdef GEN_DEBUG_MULTILIST
00434 if ( ! initDone )
00435 {
00436 MLIST_GEN_FATAL("GEN_ERROR : getElementPayload : initList has NOT been called before using list");
00437 assert (0);
00438 }
00439
00440 #endif
00441
00442 #ifdef MLIST_ARGUMENTS_TESTING
00443 if (elementIndex >= 0 && elementIndex < nbElements)
00444 {
00445 #endif
00446 return ( elementList[elementIndex].payLoad );
00447 #ifdef MLIST_ARGUMENTS_TESTING
00448 }
00449 else
00450 {
00451 MLIST_GEN_DEBUG ("GEN_ERROR : getElementPayload : out of bounds element index ( " << elementIndex << " )");
00452 return (NULL);
00453 }
00454 #endif
00455 }
00456
00457 template <class Type> int C_MultiList<Type>::setElementPayload ( long elementIndex, Type * payLoad )
00458 {
00459
00460 #ifdef GEN_DEBUG_MULTILIST
00461 if ( ! initDone )
00462 {
00463 MLIST_GEN_FATAL("GEN_ERROR : setElementPayload : initList has NOT been called before using list");
00464 assert (0);
00465 }
00466 #endif
00467
00468 #ifdef MLIST_ARGUMENTS_TESTING
00469 if (elementIndex >= 0 && elementIndex < nbElements )
00470 {
00471 #endif
00472 elementList[elementIndex].payLoad = payLoad;
00473 return ( TST_OK );
00474 #ifdef MLIST_ARGUMENTS_TESTING
00475 }
00476 else
00477 {
00478 MLIST_GEN_DEBUG("GEN_ERROR : setElementPayload : out of bounds element index ( " << elementIndex << " )");
00479 return ( TST_ERROR );
00480 }
00481 #endif
00482 }
00483
00484
00485 template <class Type> long C_MultiList<Type>::getNbElements ( long listIdx )
00486 {
00487 #ifdef GEN_DEBUG_MULTILIST
00488 MLIST_GEN_DEBUG("BEGIN getNbElements " << listIdx);
00489 #endif
00490
00491 #ifdef MLIST_ARGUMENTS_TESTING
00492 if (listIdx >= firstListIndex && listIdx <= lastListIndex)
00493 {
00494 # ifdef GEN_DEBUG_MULTILIST
00495 MLIST_GEN_DEBUG("END getNbElements : returning " << stateList[listIdx].nbElements);
00496 # endif
00497 #endif
00498 return ( stateList[listIdx].nbElements );
00499 #ifdef MLIST_ARGUMENTS_TESTING
00500 }
00501 else
00502 {
00503 MLIST_GEN_DEBUG("END getNbElements : out of bounds list index (" << listIdx << " while max index is " << lastListIndex << ")");
00504 assert (0);
00505 return (TST_ERROR);
00506 }
00507 #endif
00508 }
00509
00510 template <class Type> void C_MultiList<Type>::dump (void)
00511 {
00512 int L_int, L_cpt, L_cpt2, L_loop;
00513
00514 #ifdef GEN_DEBUG_MULTILIST
00515 if ( ! initDone )
00516 {
00517 MLIST_GEN_FATAL("initList has NOT been called before using list");
00518 assert (0);
00519 }
00520 #endif
00521
00522 MLIST_GEN_DEBUG ("-- DUMP -----------------------");
00523 for (L_loop = 0; L_loop < nbLists; L_loop++)
00524 {
00525 L_int = stateList[L_loop].firstElement;
00526 L_cpt = 0;
00527
00528 if (L_int != NULL_INDEX_ELEMENT)
00529 {
00530 L_cpt = 1;
00531 }
00532
00533 while (L_int != stateList[L_loop].lastElement)
00534 {
00535 L_cpt++;
00536 L_int = elementList[L_int].nextElement;
00537 if (L_cpt > nbElements)
00538 L_int = stateList[L_loop].lastElement;
00539
00540 if ( L_loop != elementList[L_int].currentList )
00541 {
00542 MLIST_GEN_FATAL ("(1) Element " << L_int << " found in list " << L_loop << " while having " << elementList[L_int].currentList << " as current list ???" );
00543 assert (0 );
00544 }
00545 }
00546
00547 L_int = stateList[L_loop].lastElement;
00548 L_cpt2 = 0;
00549
00550 if (L_int != NULL_INDEX_ELEMENT)
00551 {
00552 L_cpt2 = 1;
00553 }
00554
00555 while (L_int != stateList[L_loop].firstElement)
00556 {
00557 L_cpt2++;
00558 L_int = elementList[L_int].prevElement;
00559 if (L_cpt2 > nbElements)
00560 {
00561 L_int = stateList[L_loop].firstElement;
00562 }
00563
00564 if ( L_loop != elementList[L_int].currentList )
00565 {
00566 MLIST_GEN_FATAL ("(2) Element " << L_int << " found in list " << L_loop << " while having " << elementList[L_int].currentList << " as current list ???" );
00567 assert (0 );
00568 }
00569 }
00570 MLIST_GEN_DEBUG ("Nb elements in list [" << setw(6) << L_loop << "] compteur 1 :" << setw(6) << L_cpt << " compteur 2: " << setw(6) << L_cpt2 << " getNbElements " << getNbElements (L_loop) << " first element: " << setw(6) << stateList[L_loop].firstElement );
00571 }
00572 MLIST_GEN_DEBUG ("-- END OF DUMP -----------------" );
00573 };