ELIST2_ITERATOR Class Reference

#include <elst2.h>

List of all members.


Detailed Description

Doubly linked lists with embedded links; generic iterator class.

Definition at line 156 of file elst2.h.

Public Member Functions

Private Member Functions

Private Attributes

Friends


Constructor & Destructor Documentation

ELIST2_ITERATOR::ELIST2_ITERATOR (  )  [inline]

Definition at line 177 of file elst2.h.

References NULL.

00177                       {  //constructor
00178       list = NULL;
00179     }                            //unassigned list

ELIST2_ITERATOR::ELIST2_ITERATOR ( ELIST2 list_to_iterate  )  [inline]

CONSTRUCTOR; set iterator to specified list;.

Definition at line 290 of file elst2.h.

References set_to_list().

00290                                                                {
00291   set_to_list(list_to_iterate);
00292 }


Member Function Documentation

void ELIST2_ITERATOR::add_after_stay_put ( ELIST2_LINK new_link  )  [inline]

Add a new element to the list after the current element but do not move the iterator to the new element.

Definition at line 348 of file elst2.h.

References ABORT, current, ELIST2::empty(), ex_current_was_last, FALSE, ELIST2::last, list, next, ELIST2_LINK::next, NULL, prev, and ELIST2_LINK::prev.

00349                                                                           {
00350   #ifdef _DEBUG
00351   if (!this)
00352     NULL_OBJECT.error ("ELIST2_ITERATOR::add_after_stay_put", ABORT, NULL);
00353   if (!list)
00354     NO_LIST.error ("ELIST2_ITERATOR::add_after_stay_put", ABORT, NULL);
00355   if (!new_element)
00356     BAD_PARAMETER.error ("ELIST2_ITERATOR::add_after_stay_put", ABORT,
00357       "new_element is NULL");
00358   if (new_element->next)
00359     STILL_LINKED.error ("ELIST2_ITERATOR::add_after_stay_put", ABORT, NULL);
00360   #endif
00361 
00362   if (list->empty ()) {
00363     new_element->next = new_element;
00364     new_element->prev = new_element;
00365     list->last = new_element;
00366     prev = next = new_element;
00367     ex_current_was_last = FALSE;
00368     current = NULL;
00369   }
00370   else {
00371     new_element->next = next;
00372     next->prev = new_element;
00373 
00374     if (current) {               //not extracted
00375       new_element->prev = current;
00376       current->next = new_element;
00377       if (prev == current)
00378         prev = new_element;
00379       if (current == list->last)
00380         list->last = new_element;
00381     }
00382     else {                       //current extracted
00383       new_element->prev = prev;
00384       prev->next = new_element;
00385       if (ex_current_was_last) {
00386         list->last = new_element;
00387         ex_current_was_last = FALSE;
00388       }
00389     }
00390     next = new_element;
00391   }
00392 }

void ELIST2_ITERATOR::add_after_then_move ( ELIST2_LINK new_link  )  [inline]

Add a new element to the list after the current element and move the ex_current_was_cycle_pt = FALSE; iterator to the new element.

Definition at line 300 of file elst2.h.

References ABORT, current, cycle_pt, ELIST2::empty(), ex_current_was_cycle_pt, ex_current_was_last, ELIST2::last, list, next, ELIST2_LINK::next, NULL, prev, and ELIST2_LINK::prev.

Referenced by ELIST2::internal_deep_copy().

00301                                                                            {
00302   #ifdef _DEBUG
00303   if (!this)
00304     NULL_OBJECT.error ("ELIST2_ITERATOR::add_after_then_move", ABORT, NULL);
00305   if (!list)
00306     NO_LIST.error ("ELIST2_ITERATOR::add_after_then_move", ABORT, NULL);
00307   if (!new_element)
00308     BAD_PARAMETER.error ("ELIST2_ITERATOR::add_after_then_move", ABORT,
00309       "new_element is NULL");
00310   if (new_element->next)
00311     STILL_LINKED.error ("ELIST2_ITERATOR::add_after_then_move", ABORT, NULL);
00312   #endif
00313 
00314   if (list->empty ()) {
00315     new_element->next = new_element;
00316     new_element->prev = new_element;
00317     list->last = new_element;
00318     prev = next = new_element;
00319   }
00320   else {
00321     new_element->next = next;
00322     next->prev = new_element;
00323 
00324     if (current) {               //not extracted
00325       new_element->prev = current;
00326       current->next = new_element;
00327       prev = current;
00328       if (current == list->last)
00329         list->last = new_element;
00330     }
00331     else {                       //current extracted
00332       new_element->prev = prev;
00333       prev->next = new_element;
00334       if (ex_current_was_last)
00335         list->last = new_element;
00336       if (ex_current_was_cycle_pt)
00337         cycle_pt = new_element;
00338     }
00339   }
00340   current = new_element;
00341 }

void ELIST2_ITERATOR::add_before_stay_put ( ELIST2_LINK new_link  )  [inline]

Add a new element to the list before the current element but dont move the iterator to the new element.

Definition at line 445 of file elst2.h.

References ABORT, current, ELIST2::empty(), ex_current_was_last, ELIST2::last, list, next, ELIST2_LINK::next, NULL, prev, ELIST2_LINK::prev, and TRUE.

00446                                                                            {
00447   #ifdef _DEBUG
00448   if (!this)
00449     NULL_OBJECT.error ("ELIST2_ITERATOR::add_before_stay_put", ABORT, NULL);
00450   if (!list)
00451     NO_LIST.error ("ELIST2_ITERATOR::add_before_stay_put", ABORT, NULL);
00452   if (!new_element)
00453     BAD_PARAMETER.error ("ELIST2_ITERATOR::add_before_stay_put", ABORT,
00454       "new_element is NULL");
00455   if (new_element->next)
00456     STILL_LINKED.error ("ELIST2_ITERATOR::add_before_stay_put", ABORT, NULL);
00457   #endif
00458 
00459   if (list->empty ()) {
00460     new_element->next = new_element;
00461     new_element->prev = new_element;
00462     list->last = new_element;
00463     prev = next = new_element;
00464     ex_current_was_last = TRUE;
00465     current = NULL;
00466   }
00467   else {
00468     prev->next = new_element;
00469     new_element->prev = prev;
00470 
00471     if (current) {               //not extracted
00472       new_element->next = current;
00473       current->prev = new_element;
00474       if (next == current)
00475         next = new_element;
00476     }
00477     else {                       //current extracted
00478       new_element->next = next;
00479       next->prev = new_element;
00480       if (ex_current_was_last)
00481         list->last = new_element;
00482     }
00483     prev = new_element;
00484   }
00485 }

void ELIST2_ITERATOR::add_before_then_move ( ELIST2_LINK new_link  )  [inline]

Add a new element to the list before the current element and move the iterator to the new element.

Definition at line 399 of file elst2.h.

References ABORT, current, cycle_pt, ELIST2::empty(), ex_current_was_cycle_pt, ex_current_was_last, ELIST2::last, list, next, ELIST2_LINK::next, NULL, prev, and ELIST2_LINK::prev.

00400                                                                             {
00401   #ifdef _DEBUG
00402   if (!this)
00403     NULL_OBJECT.error ("ELIST2_ITERATOR::add_before_then_move", ABORT, NULL);
00404   if (!list)
00405     NO_LIST.error ("ELIST2_ITERATOR::add_before_then_move", ABORT, NULL);
00406   if (!new_element)
00407     BAD_PARAMETER.error ("ELIST2_ITERATOR::add_before_then_move", ABORT,
00408       "new_element is NULL");
00409   if (new_element->next)
00410     STILL_LINKED.error ("ELIST2_ITERATOR::add_before_then_move", ABORT, NULL);
00411   #endif
00412 
00413   if (list->empty ()) {
00414     new_element->next = new_element;
00415     new_element->prev = new_element;
00416     list->last = new_element;
00417     prev = next = new_element;
00418   }
00419   else {
00420     prev->next = new_element;
00421     new_element->prev = prev;
00422 
00423     if (current) {               //not extracted
00424       new_element->next = current;
00425       current->prev = new_element;
00426       next = current;
00427     }
00428     else {                       //current extracted
00429       new_element->next = next;
00430       next->prev = new_element;
00431       if (ex_current_was_last)
00432         list->last = new_element;
00433       if (ex_current_was_cycle_pt)
00434         cycle_pt = new_element;
00435     }
00436   }
00437   current = new_element;
00438 }

void ELIST2_ITERATOR::add_list_after ( ELIST2 list_to_add  )  [inline]

Insert another list to this list after the current element but dont move the iterator.

Definition at line 492 of file elst2.h.

References ABORT, current, ELIST2::empty(), ex_current_was_last, FALSE, ELIST2::First(), ELIST2::last, list, ELIST2_LINK::next, next, NULL, ELIST2_LINK::prev, prev, and TRUE.

00492                                                                {
00493   #ifdef _DEBUG
00494   if (!this)
00495     NULL_OBJECT.error ("ELIST2_ITERATOR::add_list_after", ABORT, NULL);
00496   if (!list)
00497     NO_LIST.error ("ELIST2_ITERATOR::add_list_after", ABORT, NULL);
00498   if (!list_to_add)
00499     BAD_PARAMETER.error ("ELIST2_ITERATOR::add_list_after", ABORT,
00500       "list_to_add is NULL");
00501   #endif
00502 
00503   if (!list_to_add->empty ()) {
00504     if (list->empty ()) {
00505       list->last = list_to_add->last;
00506       prev = list->last;
00507       next = list->First ();
00508       ex_current_was_last = TRUE;
00509       current = NULL;
00510     }
00511     else {
00512       if (current) {             //not extracted
00513         current->next = list_to_add->First ();
00514         current->next->prev = current;
00515         if (current == list->last)
00516           list->last = list_to_add->last;
00517         list_to_add->last->next = next;
00518         next->prev = list_to_add->last;
00519         next = current->next;
00520       }
00521       else {                     //current extracted
00522         prev->next = list_to_add->First ();
00523         prev->next->prev = prev;
00524         if (ex_current_was_last) {
00525           list->last = list_to_add->last;
00526           ex_current_was_last = FALSE;
00527         }
00528         list_to_add->last->next = next;
00529         next->prev = list_to_add->last;
00530         next = prev->next;
00531       }
00532     }
00533     list_to_add->last = NULL;
00534   }
00535 }

void ELIST2_ITERATOR::add_list_before ( ELIST2 list_to_add  )  [inline]

Insert another list to this list before the current element. Move the iterator to the start of the inserted elements iterator.

Definition at line 542 of file elst2.h.

References ABORT, current, cycle_pt, ELIST2::empty(), ex_current_was_cycle_pt, ex_current_was_last, FALSE, ELIST2::First(), ELIST2::last, list, ELIST2_LINK::next, next, NULL, ELIST2_LINK::prev, and prev.

00542                                                                 {
00543   #ifdef _DEBUG
00544   if (!this)
00545     NULL_OBJECT.error ("ELIST2_ITERATOR::add_list_before", ABORT, NULL);
00546   if (!list)
00547     NO_LIST.error ("ELIST2_ITERATOR::add_list_before", ABORT, NULL);
00548   if (!list_to_add)
00549     BAD_PARAMETER.error ("ELIST2_ITERATOR::add_list_before", ABORT,
00550       "list_to_add is NULL");
00551   #endif
00552 
00553   if (!list_to_add->empty ()) {
00554     if (list->empty ()) {
00555       list->last = list_to_add->last;
00556       prev = list->last;
00557       current = list->First ();
00558       next = current->next;
00559       ex_current_was_last = FALSE;
00560     }
00561     else {
00562       prev->next = list_to_add->First ();
00563       prev->next->prev = prev;
00564 
00565       if (current) {             //not extracted
00566         list_to_add->last->next = current;
00567         current->prev = list_to_add->last;
00568       }
00569       else {                     //current extracted
00570         list_to_add->last->next = next;
00571         next->prev = list_to_add->last;
00572         if (ex_current_was_last)
00573           list->last = list_to_add->last;
00574         if (ex_current_was_cycle_pt)
00575           cycle_pt = prev->next;
00576       }
00577       current = prev->next;
00578       next = current->next;
00579     }
00580     list_to_add->last = NULL;
00581   }
00582 }

void ELIST2_ITERATOR::add_to_end ( ELIST2_LINK new_element  )  [inline]

Add a new element to the end of the list without moving the iterator.

This is provided because a single linked list cannot move to the last as the iterator couldn't set its prev pointer. Adding to the end is essential for implementing queues.

Definition at line 789 of file elst2.h.

References ABORT, ELIST2::last, list, ELIST2_LINK::next, NULL, and ELIST2_LINK::prev.

Referenced by ELIST2::internal_de_dump(), and ELIST2::sort().

00790                                                                   {
00791   #ifdef _DEBUG
00792   if (!this)
00793     NULL_OBJECT.error ("ELIST2_ITERATOR::add_to_end", ABORT, NULL);
00794   if (!list)
00795     NO_LIST.error ("ELIST2_ITERATOR::add_to_end", ABORT, NULL);
00796   if (!new_element)
00797     BAD_PARAMETER.error ("ELIST2_ITERATOR::add_to_end", ABORT,
00798       "new_element is NULL");
00799   if (new_element->next)
00800     STILL_LINKED.error ("ELIST2_ITERATOR::add_to_end", ABORT, NULL);
00801   #endif
00802 
00803   if (this->at_last ()) {
00804     this->add_after_stay_put (new_element);
00805   }
00806   else {
00807     if (this->at_first ()) {
00808       this->add_before_stay_put (new_element);
00809       list->last = new_element;
00810     }
00811     else {                       //Iteratr is elsewhere
00812       new_element->next = list->last->next;
00813       new_element->prev = list->last;
00814       list->last->next->prev = new_element;
00815       list->last->next = new_element;
00816       list->last = new_element;
00817     }
00818   }
00819 }

BOOL8 ELIST2_ITERATOR::at_first (  )  [inline]

Are we at the start of the list?

Definition at line 699 of file elst2.h.

References ABORT, current, ELIST2::empty(), ex_current_was_last, ELIST2::First(), ELIST2::last, list, NULL, and prev.

00699                                        {
00700   #ifdef _DEBUG
00701   if (!this)
00702     NULL_OBJECT.error ("ELIST2_ITERATOR::at_first", ABORT, NULL);
00703   if (!list)
00704     NO_LIST.error ("ELIST2_ITERATOR::at_first", ABORT, NULL);
00705   #endif
00706 
00707                                  //we're at a deleted
00708   return ((list->empty ()) || (current == list->First ()) || ((current == NULL) &&
00709     (prev == list->last) &&      //NON-last pt between
00710     !ex_current_was_last));      //first and last
00711 }

BOOL8 ELIST2_ITERATOR::at_last (  )  [inline]

Are we at the end of the list?

Definition at line 717 of file elst2.h.

References ABORT, current, ELIST2::empty(), ex_current_was_last, ELIST2::last, list, NULL, and prev.

Referenced by extract_sublist().

00717                                       {
00718   #ifdef _DEBUG
00719   if (!this)
00720     NULL_OBJECT.error ("ELIST2_ITERATOR::at_last", ABORT, NULL);
00721   if (!list)
00722     NO_LIST.error ("ELIST2_ITERATOR::at_last", ABORT, NULL);
00723   #endif
00724 
00725                                  //we're at a deleted
00726   return ((list->empty ()) || (current == list->last) || ((current == NULL) &&
00727     (prev == list->last) &&      //last point between
00728     ex_current_was_last));       //first and last
00729 }

ELIST2_LINK * ELIST2_ITERATOR::backward (  ) 

Move the iterator to the previous element of the list.

REMEMBER: ALL LISTS ARE CIRCULAR.

Definition at line 318 of file elst2.cpp.

References ABORT, current, cycle_pt, ELIST2::empty(), ex_current_was_cycle_pt, list, next, NULL, ELIST2_LINK::prev, prev, started_cycling, and TRUE.

00318                                        {
00319   #ifdef _DEBUG
00320   if (!this)
00321     NULL_OBJECT.error ("ELIST2_ITERATOR::backward", ABORT, NULL);
00322   if (!list)
00323     NO_LIST.error ("ELIST2_ITERATOR::backward", ABORT, NULL);
00324   #endif
00325   if (list->empty ())
00326     return NULL;
00327 
00328   if (current) {                 //not removed so
00329                                  //set previous
00330     next = current;
00331     started_cycling = TRUE;
00332   }
00333   else {
00334     if (ex_current_was_cycle_pt)
00335       cycle_pt = prev;
00336   }
00337   current = prev;
00338   prev = current->prev;
00339 
00340   #ifdef _DEBUG
00341   if (!current)
00342     NULL_DATA.error ("ELIST2_ITERATOR::backward", ABORT, NULL);
00343   if (!prev)
00344     NULL_PREV.error ("ELIST2_ITERATOR::backward", ABORT,
00345       "This is: %i  Current is: %i",
00346       (int) this, (int) current);
00347   #endif
00348   return current;
00349 }

BOOL8 ELIST2_ITERATOR::current_extracted (  )  [inline]

Definition at line 239 of file elst2.h.

00239                               {  //current extracted?
00240       return !current;
00241     }

BOOL8 ELIST2_ITERATOR::cycled_list (  )  [inline]

Have we returned to the cycle_pt since it was set?

Definition at line 735 of file elst2.h.

References ABORT, current, cycle_pt, ELIST2::empty(), list, NULL, and started_cycling.

Referenced by extract_sublist(), ELIST2::internal_deep_copy(), ELIST2::internal_dump(), ELIST2::length(), ELIST2::prep_serialise(), and ELIST2::sort().

00735                                           {
00736   #ifdef _DEBUG
00737   if (!this)
00738     NULL_OBJECT.error ("ELIST2_ITERATOR::cycled_list", ABORT, NULL);
00739   if (!list)
00740     NO_LIST.error ("ELIST2_ITERATOR::cycled_list", ABORT, NULL);
00741   #endif
00742 
00743   return ((list->empty ()) || ((current == cycle_pt) && started_cycling));
00744 
00745 }

ELIST2_LINK* ELIST2_ITERATOR::data (  )  [inline]

Definition at line 205 of file elst2.h.

References ABORT, and NULL.

Referenced by ELIST2::internal_deep_copy(), and ELIST2::internal_dump().

00205                         {  //get current data
00206     #ifdef _DEBUG
00207       if (!current)
00208         NULL_DATA.error ("ELIST2_ITERATOR::data", ABORT, NULL);
00209       if (!list)
00210         NO_LIST.error ("ELIST2_ITERATOR::data", ABORT, NULL);
00211     #endif
00212       return current;
00213     }

ELIST2_LINK * ELIST2_ITERATOR::data_relative ( INT8  offset  ) 

Return the data pointer to the element "offset" elements from current.

This function can't be INLINEd because it contains a loop

Definition at line 357 of file elst2.cpp.

References ABORT, current, ELIST2::empty(), list, ELIST2_LINK::next, next, NULL, prev, and ELIST2_LINK::prev.

00358                    {  //offset from current
00359   ELIST2_LINK *ptr;
00360 
00361   #ifdef _DEBUG
00362   if (!this)
00363     NULL_OBJECT.error ("ELIST2_ITERATOR::data_relative", ABORT, NULL);
00364   if (!list)
00365     NO_LIST.error ("ELIST2_ITERATOR::data_relative", ABORT, NULL);
00366   if (list->empty ())
00367     EMPTY_LIST.error ("ELIST2_ITERATOR::data_relative", ABORT, NULL);
00368   #endif
00369 
00370   if (offset < 0)
00371     for (ptr = current ? current : next; offset++ < 0; ptr = ptr->prev);
00372   else
00373     for (ptr = current ? current : prev; offset-- > 0; ptr = ptr->next);
00374 
00375   #ifdef _DEBUG
00376   if (!ptr)
00377     NULL_DATA.error ("ELIST2_ITERATOR::data_relative", ABORT, NULL);
00378   #endif
00379 
00380   return ptr;
00381 }

BOOL8 ELIST2_ITERATOR::empty (  )  [inline]

Definition at line 231 of file elst2.h.

References ABORT, and NULL.

00231                   {  //is list empty?
00232     #ifdef _DEBUG
00233       if (!list)
00234         NO_LIST.error ("ELIST2_ITERATOR::empty", ABORT, NULL);
00235     #endif
00236       return list->empty ();
00237     }

void ELIST2_ITERATOR::exchange ( ELIST2_ITERATOR other_it  ) 

Given another iterator, whose current element is a different element on the same list list OR an element of another list, exchange the two current elements.

On return, each iterator points to the element which was the other iterators current on entry. This function hasn't been in-lined because its a bit big!

Definition at line 393 of file elst2.cpp.

References ABORT, current, cycle_pt, ELIST2::empty(), ERRCODE::error(), ELIST2::last, list, ELIST2_LINK::next, next, NULL, ELIST2_LINK::prev, and prev.

00394                                    {  //other iterator
00395   const ERRCODE DONT_EXCHANGE_DELETED =
00396     "Can't exchange deleted elements of lists";
00397 
00398   ELIST2_LINK *old_current;
00399 
00400   #ifdef _DEBUG
00401   if (!this)
00402     NULL_OBJECT.error ("ELIST2_ITERATOR::exchange", ABORT, NULL);
00403   if (!list)
00404     NO_LIST.error ("ELIST2_ITERATOR::exchange", ABORT, NULL);
00405   if (!other_it)
00406     BAD_PARAMETER.error ("ELIST2_ITERATOR::exchange", ABORT, "other_it NULL");
00407   if (!(other_it->list))
00408     NO_LIST.error ("ELIST2_ITERATOR::exchange", ABORT, "other_it");
00409   #endif
00410 
00411   /* Do nothing if either list is empty or if both iterators
00412   reference the same link */
00413 
00414   if ((list->empty ()) ||
00415     (other_it->list->empty ()) || (current == other_it->current))
00416     return;
00417 
00418   /* Error if either current element is deleted */
00419 
00420   if (!current || !other_it->current)
00421     DONT_EXCHANGE_DELETED.error ("ELIST2_ITERATOR.exchange", ABORT, NULL);
00422 
00423   /* Now handle the 4 cases:
00424    doubleton list;
00425    non-doubleton adjacent elements (other before this);
00426    non-doubleton adjacent elements (this before other);
00427     non-adjacent elements. */
00428 
00429                                  //adjacent links
00430   if ((next == other_it->current) ||
00431   (other_it->next == current)) {
00432                                  //doubleton list
00433     if ((next == other_it->current) &&
00434     (other_it->next == current)) {
00435       prev = next = current;
00436       other_it->prev = other_it->next = other_it->current;
00437     }
00438     else {                       //non-doubleton with
00439                                  //adjacent links
00440                                  //other before this
00441       if (other_it->next == current) {
00442         other_it->prev->next = current;
00443         other_it->current->next = next;
00444         other_it->current->prev = current;
00445         current->next = other_it->current;
00446         current->prev = other_it->prev;
00447         next->prev = other_it->current;
00448 
00449         other_it->next = other_it->current;
00450         prev = current;
00451       }
00452       else {                     //this before other
00453         prev->next = other_it->current;
00454         current->next = other_it->next;
00455         current->prev = other_it->current;
00456         other_it->current->next = current;
00457         other_it->current->prev = prev;
00458         other_it->next->prev = current;
00459 
00460         next = current;
00461         other_it->prev = other_it->current;
00462       }
00463     }
00464   }
00465   else {                         //no overlap
00466     prev->next = other_it->current;
00467     current->next = other_it->next;
00468     current->prev = other_it->prev;
00469     next->prev = other_it->current;
00470     other_it->prev->next = current;
00471     other_it->current->next = next;
00472     other_it->current->prev = prev;
00473     other_it->next->prev = current;
00474   }
00475 
00476   /* update end of list pointer when necessary (remember that the 2
00477   iterators may iterate over different lists!) */
00478 
00479   if (list->last == current)
00480     list->last = other_it->current;
00481   if (other_it->list->last == other_it->current)
00482     other_it->list->last = current;
00483 
00484   if (current == cycle_pt)
00485     cycle_pt = other_it->cycle_pt;
00486   if (other_it->current == other_it->cycle_pt)
00487     other_it->cycle_pt = cycle_pt;
00488 
00489   /* The actual exchange - in all cases*/
00490 
00491   old_current = current;
00492   current = other_it->current;
00493   other_it->current = old_current;
00494 }

ELIST2_LINK * ELIST2_ITERATOR::extract (  )  [inline]

Do extraction by removing current from the list, returning it to the caller, but NOT updating the iterator.

Any calling loop can do this. The iterator's current points to NULL. If the extracted element is to be deleted, this is the callers responsibility.

Definition at line 592 of file elst2.h.

References ABORT, current, cycle_pt, ex_current_was_cycle_pt, ex_current_was_last, FALSE, ELIST2::last, list, ELIST2_LINK::next, next, NULL, ELIST2_LINK::prev, prev, ELIST2::singleton(), and TRUE.

Referenced by ELIST2::sort().

00592                                              {
00593   ELIST2_LINK *extracted_link;
00594 
00595   #ifdef _DEBUG
00596   if (!this)
00597     NULL_OBJECT.error ("ELIST2_ITERATOR::extract", ABORT, NULL);
00598   if (!list)
00599     NO_LIST.error ("ELIST2_ITERATOR::extract", ABORT, NULL);
00600   if (!current)                  //list empty or
00601                                  //element extracted
00602     NULL_CURRENT.error ("ELIST2_ITERATOR::extract",
00603       ABORT, NULL);
00604   #endif
00605 
00606   if (list->singleton ())        //special case where
00607                                  //we do need to
00608     prev = next = list->last = NULL;
00609   //change the iterator
00610   else {
00611     prev->next = next;           //remove from list
00612     next->prev = prev;
00613 
00614     if (current == list->last) {
00615       list->last = prev;
00616       ex_current_was_last = TRUE;
00617     }
00618     else
00619       ex_current_was_last = FALSE;
00620 
00621     ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
00622 
00623   }
00624   extracted_link = current;
00625   extracted_link->next = NULL;   //for safety
00626   extracted_link->prev = NULL;   //for safety
00627   current = NULL;
00628   return extracted_link;
00629 }

ELIST2_LINK * ELIST2_ITERATOR::extract_sublist ( ELIST2_ITERATOR other_it  )  [private]

This is a private member, used only by ELIST2::assign_to_sublist.

Given another iterator for the same list, extract the links from THIS to OTHER inclusive, link them into a new circular list, and return a pointer to the last element. Can't inline this function because it contains a loop

Definition at line 505 of file elst2.cpp.

References ABORT, at_last(), current, cycle_pt, cycled_list(), ELIST2::empty(), ERRCODE::error(), ex_current_was_cycle_pt, ex_current_was_last, FALSE, forward(), ELIST2::last, list, mark_cycle_pt(), next, ELIST2_LINK::next, NULL, ELIST2_LINK::prev, prev, and TRUE.

Referenced by ELIST2::assign_to_sublist().

00506                                      {  //to other current
00507   #ifdef _DEBUG
00508   const ERRCODE BAD_EXTRACTION_PTS =
00509     "Can't extract sublist from points on different lists";
00510   const ERRCODE DONT_EXTRACT_DELETED =
00511     "Can't extract a sublist marked by deleted points";
00512   #endif
00513   const ERRCODE BAD_SUBLIST = "Can't find sublist end point in original list";
00514 
00515   ELIST2_ITERATOR temp_it = *this;
00516   ELIST2_LINK *end_of_new_list;
00517 
00518   #ifdef _DEBUG
00519   if (!this)
00520     NULL_OBJECT.error ("ELIST2_ITERATOR::extract_sublist", ABORT, NULL);
00521   if (!other_it)
00522     BAD_PARAMETER.error ("ELIST2_ITERATOR::extract_sublist", ABORT,
00523       "other_it NULL");
00524   if (!list)
00525     NO_LIST.error ("ELIST2_ITERATOR::extract_sublist", ABORT, NULL);
00526   if (list != other_it->list)
00527     BAD_EXTRACTION_PTS.error ("ELIST2_ITERATOR.extract_sublist", ABORT, NULL);
00528   if (list->empty ())
00529     EMPTY_LIST.error ("ELIST2_ITERATOR::extract_sublist", ABORT, NULL);
00530 
00531   if (!current || !other_it->current)
00532     DONT_EXTRACT_DELETED.error ("ELIST2_ITERATOR.extract_sublist", ABORT,
00533       NULL);
00534   #endif
00535 
00536   ex_current_was_last = other_it->ex_current_was_last = FALSE;
00537   ex_current_was_cycle_pt = FALSE;
00538   other_it->ex_current_was_cycle_pt = FALSE;
00539 
00540   temp_it.mark_cycle_pt ();
00541   do {                           //walk sublist
00542     if (temp_it.cycled_list ())  //cant find end pt
00543       BAD_SUBLIST.error ("ELIST2_ITERATOR.extract_sublist", ABORT, NULL);
00544 
00545     if (temp_it.at_last ()) {
00546       list->last = prev;
00547       ex_current_was_last = other_it->ex_current_was_last = TRUE;
00548     }
00549 
00550     if (temp_it.current == cycle_pt)
00551       ex_current_was_cycle_pt = TRUE;
00552 
00553     if (temp_it.current == other_it->cycle_pt)
00554       other_it->ex_current_was_cycle_pt = TRUE;
00555 
00556     temp_it.forward ();
00557   }
00558                                  //do INCLUSIVE list
00559   while (temp_it.prev != other_it->current);
00560 
00561                                  //circularise sublist
00562   other_it->current->next = current;
00563                                  //circularise sublist
00564   current->prev = other_it->current;
00565   end_of_new_list = other_it->current;
00566 
00567                                  //sublist = whole list
00568   if (prev == other_it->current) {
00569     list->last = NULL;
00570     prev = current = next = NULL;
00571     other_it->prev = other_it->current = other_it->next = NULL;
00572   }
00573   else {
00574     prev->next = other_it->next;
00575     other_it->next->prev = prev;
00576 
00577     current = other_it->current = NULL;
00578     next = other_it->next;
00579     other_it->prev = prev;
00580   }
00581   return end_of_new_list;
00582 }

ELIST2_LINK * ELIST2_ITERATOR::forward (  ) 

Move the iterator to the next element of the list.

REMEMBER: ALL LISTS ARE CIRCULAR.

Definition at line 279 of file elst2.cpp.

References ABORT, current, cycle_pt, ELIST2::empty(), ex_current_was_cycle_pt, list, ELIST2_LINK::next, next, NULL, prev, started_cycling, and TRUE.

Referenced by extract_sublist(), ELIST2::internal_deep_copy(), ELIST2::internal_dump(), ELIST2::length(), ELIST2::prep_serialise(), and ELIST2::sort().

00279                                       {
00280   #ifdef _DEBUG
00281   if (!this)
00282     NULL_OBJECT.error ("ELIST2_ITERATOR::forward", ABORT, NULL);
00283   if (!list)
00284     NO_LIST.error ("ELIST2_ITERATOR::forward", ABORT, NULL);
00285   #endif
00286   if (list->empty ())
00287     return NULL;
00288 
00289   if (current) {                 //not removed so
00290                                  //set previous
00291     prev = current;
00292     started_cycling = TRUE;
00293   }
00294   else {
00295     if (ex_current_was_cycle_pt)
00296       cycle_pt = next;
00297   }
00298   current = next;
00299   next = current->next;
00300 
00301   #ifdef _DEBUG
00302   if (!current)
00303     NULL_DATA.error ("ELIST2_ITERATOR::forward", ABORT, NULL);
00304   if (!next)
00305     NULL_NEXT.error ("ELIST2_ITERATOR::forward", ABORT,
00306       "This is: %i  Current is: %i",
00307       (int) this, (int) current);
00308   #endif
00309   return current;
00310 }

INT32 ELIST2_ITERATOR::length (  )  [inline]

Return the length of the list.

Definition at line 751 of file elst2.h.

References ABORT, ELIST2::length(), list, and NULL.

00751                                      {
00752   #ifdef _DEBUG
00753   if (!this)
00754     NULL_OBJECT.error ("ELIST2_ITERATOR::length", ABORT, NULL);
00755   if (!list)
00756     NO_LIST.error ("ELIST2_ITERATOR::length", ABORT, NULL);
00757   #endif
00758 
00759   return list->length ();
00760 }

void ELIST2_ITERATOR::mark_cycle_pt (  )  [inline]

Remember the current location so that we can tell whether we've returned to this point later.

If the current point is deleted either now, or in the future, the cycle point will be set to the next item which is set to current. This could be by a forward, add_after_then_move or add_after_then_move.

Definition at line 680 of file elst2.h.

References ABORT, current, cycle_pt, ex_current_was_cycle_pt, FALSE, list, NULL, started_cycling, and TRUE.

Referenced by extract_sublist(), ELIST2::internal_deep_copy(), ELIST2::internal_dump(), ELIST2::length(), ELIST2::prep_serialise(), and ELIST2::sort().

00680                                            {
00681   #ifdef _DEBUG
00682   if (!this)
00683     NULL_OBJECT.error ("ELIST2_ITERATOR::mark_cycle_pt", ABORT, NULL);
00684   if (!list)
00685     NO_LIST.error ("ELIST2_ITERATOR::mark_cycle_pt", ABORT, NULL);
00686   #endif
00687 
00688   if (current)
00689     cycle_pt = current;
00690   else
00691     ex_current_was_cycle_pt = TRUE;
00692   started_cycling = FALSE;
00693 }

ELIST2_LINK * ELIST2_ITERATOR::move_to_first (  )  [inline]

Move current so that it is set to the start of the list.

Return data just in case anyone wants it.

Definition at line 637 of file elst2.h.

References ABORT, current, ELIST2::First(), ELIST2::last, list, ELIST2_LINK::next, next, NULL, and prev.

Referenced by sort().

00637                                                    {
00638   #ifdef _DEBUG
00639   if (!this)
00640     NULL_OBJECT.error ("ELIST2_ITERATOR::move_to_first", ABORT, NULL);
00641   if (!list)
00642     NO_LIST.error ("ELIST2_ITERATOR::move_to_first", ABORT, NULL);
00643   #endif
00644 
00645   current = list->First ();
00646   prev = list->last;
00647   next = current ? current->next : NULL;
00648   return current;
00649 }

ELIST2_LINK * ELIST2_ITERATOR::move_to_last (  )  [inline]

Move current so that it is set to the end of the list.

Return data just in case anyone wants it.

Definition at line 657 of file elst2.h.

References ABORT, current, ELIST2::last, list, ELIST2_LINK::next, next, NULL, ELIST2_LINK::prev, and prev.

00657                                                   {
00658   #ifdef _DEBUG
00659   if (!this)
00660     NULL_OBJECT.error ("ELIST2_ITERATOR::move_to_last", ABORT, NULL);
00661   if (!list)
00662     NO_LIST.error ("ELIST2_ITERATOR::move_to_last", ABORT, NULL);
00663   #endif
00664 
00665   current = list->last;
00666   prev = current ? current->prev : NULL;
00667   next = current ? current->next : NULL;
00668   return current;
00669 }

void ELIST2_ITERATOR::set_to_list ( ELIST2 list_to_iterate  )  [inline]

Re initialise the iterator to point to the start of the list_to_iterate over.

Definition at line 266 of file elst2.h.

References ABORT, current, cycle_pt, ex_current_was_cycle_pt, ex_current_was_last, FALSE, ELIST2::First(), ELIST2::last, list, ELIST2_LINK::next, next, NULL, prev, and started_cycling.

Referenced by ELIST2_ITERATOR(), and ELIST2::internal_de_dump().

00267                                                                   {
00268   #ifdef _DEBUG
00269   if (!this)
00270     NULL_OBJECT.error ("ELIST2_ITERATOR::set_to_list", ABORT, NULL);
00271   if (!list_to_iterate)
00272     BAD_PARAMETER.error ("ELIST2_ITERATOR::set_to_list", ABORT,
00273       "list_to_iterate is NULL");
00274   #endif
00275 
00276   list = list_to_iterate;
00277   prev = list->last;
00278   current = list->First ();
00279   next = current ? current->next : NULL;
00280   cycle_pt = NULL;               //await explicit set
00281   started_cycling = FALSE;
00282   ex_current_was_last = FALSE;
00283   ex_current_was_cycle_pt = FALSE;
00284 }

void ELIST2_ITERATOR::sort ( int   comparator(const void *, const void *)  )  [inline]

Sort the elements of the list, then reposition at the start.

Definition at line 767 of file elst2.h.

References ABORT, list, move_to_first(), NULL, and ELIST2::sort().

00769                              {
00770   #ifdef _DEBUG
00771   if (!this)
00772     NULL_OBJECT.error ("ELIST2_ITERATOR::sort", ABORT, NULL);
00773   if (!list)
00774     NO_LIST.error ("ELIST2_ITERATOR::sort", ABORT, NULL);
00775   #endif
00776 
00777   list->sort (comparator);
00778   move_to_first();
00779 }


Friends And Related Function Documentation

void ELIST2::assign_to_sublist ( ELIST2_ITERATOR ,
ELIST2_ITERATOR  
) [friend]


Member Data Documentation

ELIST2_LINK* ELIST2_ITERATOR::current [private]

Definition at line 162 of file elst2.h.

Referenced by add_after_stay_put(), add_after_then_move(), add_before_stay_put(), add_before_then_move(), add_list_after(), add_list_before(), at_first(), at_last(), backward(), cycled_list(), data_relative(), exchange(), extract(), extract_sublist(), forward(), mark_cycle_pt(), move_to_first(), move_to_last(), and set_to_list().

ELIST2_LINK* ELIST2_ITERATOR::cycle_pt [private]

Definition at line 168 of file elst2.h.

Referenced by add_after_then_move(), add_before_then_move(), add_list_before(), backward(), cycled_list(), exchange(), extract(), extract_sublist(), forward(), mark_cycle_pt(), and set_to_list().

BOOL8 ELIST2_ITERATOR::ex_current_was_cycle_pt [private]

Definition at line 166 of file elst2.h.

Referenced by add_after_then_move(), add_before_then_move(), add_list_before(), backward(), extract(), extract_sublist(), forward(), mark_cycle_pt(), and set_to_list().

BOOL8 ELIST2_ITERATOR::ex_current_was_last [private]

Definition at line 164 of file elst2.h.

Referenced by add_after_stay_put(), add_after_then_move(), add_before_stay_put(), add_before_then_move(), add_list_after(), add_list_before(), at_first(), at_last(), extract(), extract_sublist(), and set_to_list().

ELIST2* ELIST2_ITERATOR::list [private]

Definition at line 160 of file elst2.h.

Referenced by add_after_stay_put(), add_after_then_move(), add_before_stay_put(), add_before_then_move(), add_list_after(), add_list_before(), add_to_end(), at_first(), at_last(), backward(), cycled_list(), data_relative(), exchange(), extract(), extract_sublist(), forward(), length(), mark_cycle_pt(), move_to_first(), move_to_last(), set_to_list(), and sort().

ELIST2_LINK* ELIST2_ITERATOR::next [private]

Definition at line 163 of file elst2.h.

Referenced by add_after_stay_put(), add_after_then_move(), add_before_stay_put(), add_before_then_move(), add_list_after(), add_list_before(), backward(), data_relative(), exchange(), extract(), extract_sublist(), forward(), move_to_first(), move_to_last(), and set_to_list().

ELIST2_LINK* ELIST2_ITERATOR::prev [private]

Definition at line 161 of file elst2.h.

Referenced by add_after_stay_put(), add_after_then_move(), add_before_stay_put(), add_before_then_move(), add_list_after(), add_list_before(), at_first(), at_last(), backward(), data_relative(), exchange(), extract(), extract_sublist(), forward(), move_to_first(), move_to_last(), and set_to_list().

BOOL8 ELIST2_ITERATOR::started_cycling [private]

Definition at line 170 of file elst2.h.

Referenced by backward(), cycled_list(), forward(), mark_cycle_pt(), and set_to_list().


The documentation for this class was generated from the following files:
Generated on Wed Feb 28 19:49:31 2007 for Tesseract by  doxygen 1.5.1