ccutil/elst2.h

Go to the documentation of this file.
00001 
00020 #ifndef ELST2_H
00021 #define ELST2_H
00022 
00023 #include <stdio.h>
00024 #include "host.h"
00025 #include "serialis.h"
00026 #include "lsterr.h"
00027 
00028 class ELIST2_ITERATOR;
00029 
00058 class DLLSYM ELIST2_LINK
00059 {
00060   friend class ELIST2_ITERATOR;
00061   friend class ELIST2;
00062 
00063   ELIST2_LINK *prev;
00064   ELIST2_LINK *next;
00065 
00066   public:
00067     ELIST2_LINK() {  //constructor
00068       prev = next = NULL;
00069     }
00070 
00071     ELIST2_LINK(                        //copy constructor
00072                 const ELIST2_LINK &) {  //dont copy link
00073       prev = next = NULL;
00074     }
00075 
00076     void operator= (             //dont copy links
00077     const ELIST2_LINK &) {
00078       prev = next = NULL;
00079     }
00080 
00081 };
00082 
00091 class DLLSYM ELIST2
00092 {
00093   friend class ELIST2_ITERATOR;
00094 
00095   ELIST2_LINK *last;             //End of list
00096   //(Points to head)
00097   ELIST2_LINK *First() {  // return first
00098     return last ? last->next : NULL;
00099   }
00100 
00101   public:
00102     ELIST2() {  //constructor
00103       last = NULL;
00104     }
00105 
00106     void internal_clear (        //destroy all links
00107       void (*zapper) (ELIST2_LINK *));
00108     //ptr to zapper functn
00109 
00110     BOOL8 empty() {  //is list empty?
00111       return !last;
00112     }
00113 
00114     BOOL8 singleton() {
00115       return last ? (last == last->next) : FALSE;
00116     }
00117 
00118     void shallow_copy(                      //dangerous!!
00119                       ELIST2 *from_list) {  //beware destructors!!
00120       last = from_list->last;
00121     }
00122 
00123                                  //ptr to copier functn
00124     void internal_deep_copy (ELIST2_LINK * (*copier) (ELIST2_LINK *),
00125       const ELIST2 * list);      //list being copied
00126 
00127     void assign_to_sublist(                            //to this list
00128                            ELIST2_ITERATOR *start_it,  //from list start
00129                            ELIST2_ITERATOR *end_it);   //from list end
00130 
00131     INT32 length();  //# elements in list
00132 
00133     void sort (                  //sort elements
00134       int comparator (           //comparison routine
00135       const void *, const void *));
00136 
00137     void internal_dump (         //serialise each elem
00138       FILE * f,                  //to this file
00139       void element_serialiser (  //using this function
00140       FILE *, ELIST2_LINK *));
00141 
00142     void internal_de_dump (      //de_serial each elem
00143       FILE * f,                  //from this file
00144                                  //using this function
00145       ELIST2_LINK * element_de_serialiser (
00146       FILE *));
00147 
00148     void prep_serialise();  //change last to count
00149 
00150 };
00151 
00156 class DLLSYM ELIST2_ITERATOR
00157 {
00158   friend void ELIST2::assign_to_sublist(ELIST2_ITERATOR *, ELIST2_ITERATOR *);
00159 
00160   ELIST2 *list;                  //List being iterated
00161   ELIST2_LINK *prev;             //prev element
00162   ELIST2_LINK *current;          //current element
00163   ELIST2_LINK *next;             //next element
00164   BOOL8 ex_current_was_last;     //current extracted
00165   //was end of list
00166   BOOL8 ex_current_was_cycle_pt; //current extracted
00167   //was cycle point
00168   ELIST2_LINK *cycle_pt;         //point we are cycling
00169   //the list to.
00170   BOOL8 started_cycling;         //Have we moved off
00171   //the start?
00172 
00173   ELIST2_LINK *extract_sublist(                             //from this current...
00174                                ELIST2_ITERATOR *other_it);  //to other current
00175 
00176   public:
00177     ELIST2_ITERATOR() {  //constructor
00178       list = NULL;
00179     }                            //unassigned list
00180 
00181     ELIST2_ITERATOR(  //constructor
00182                     ELIST2 *list_to_iterate);
00183 
00184     void set_to_list(  //change list
00185                      ELIST2 *list_to_iterate);
00186 
00187     void add_after_then_move(                         //add after current &
00188                              ELIST2_LINK *new_link);  //move to new
00189 
00190     void add_after_stay_put(                         //add after current &
00191                             ELIST2_LINK *new_link);  //stay at current
00192 
00193     void add_before_then_move(                         //add before current &
00194                               ELIST2_LINK *new_link);  //move to new
00195 
00196     void add_before_stay_put(                         //add before current &
00197                              ELIST2_LINK *new_link);  //stay at current
00198 
00199     void add_list_after(                       //add a list &
00200                         ELIST2 *list_to_add);  //stay at current
00201 
00202     void add_list_before(                       //add a list &
00203                          ELIST2 *list_to_add);  //move to it 1st item
00204 
00205     ELIST2_LINK *data() {  //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     }
00214 
00215     ELIST2_LINK *data_relative(               //get data + or - ...
00216                                INT8 offset);  //offset from current
00217 
00218     ELIST2_LINK *forward();  //move to next element
00219 
00220     ELIST2_LINK *backward();  //move to prev element
00221 
00222     ELIST2_LINK *extract();  //remove from list
00223 
00224                                  //go to start of list
00225     ELIST2_LINK *move_to_first();
00226 
00227     ELIST2_LINK *move_to_last();  //go to end of list
00228 
00229     void mark_cycle_pt();  //remember current
00230 
00231     BOOL8 empty() {  //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     }
00238 
00239     BOOL8 current_extracted() {  //current extracted?
00240       return !current;
00241     }
00242 
00243     BOOL8 at_first();  //Current is first?
00244 
00245     BOOL8 at_last();  //Current is last?
00246 
00247     BOOL8 cycled_list();  //Completed a cycle?
00248 
00249     void add_to_end(                         //add at end &
00250                     ELIST2_LINK *new_link);  //dont move
00251 
00252     void exchange(                             //positions of 2 links
00253                   ELIST2_ITERATOR *other_it);  //other iterator
00254 
00255     INT32 length();  //# elements in list
00256 
00257     void sort (                  //sort elements
00258       int comparator (           //comparison routine
00259       const void *, const void *));
00260 
00261 };
00262 
00266 inline void ELIST2_ITERATOR::set_to_list(  //change list
00267                                          ELIST2 *list_to_iterate) {
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 }
00285 
00286 
00290 inline ELIST2_ITERATOR::ELIST2_ITERATOR(ELIST2 *list_to_iterate) {
00291   set_to_list(list_to_iterate);
00292 }
00293 
00294 
00300 inline void ELIST2_ITERATOR::add_after_then_move(  // element to add
00301                                                  ELIST2_LINK *new_element) {
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 }
00342 
00343 
00348 inline void ELIST2_ITERATOR::add_after_stay_put(  // element to add
00349                                                 ELIST2_LINK *new_element) {
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 }
00393 
00394 
00399 inline void ELIST2_ITERATOR::add_before_then_move(  // element to add
00400                                                   ELIST2_LINK *new_element) {
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 }
00439 
00440 
00445 inline void ELIST2_ITERATOR::add_before_stay_put(  // element to add
00446                                                  ELIST2_LINK *new_element) {
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 }
00486 
00487 
00492 inline void ELIST2_ITERATOR::add_list_after(ELIST2 *list_to_add) {
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 }
00536 
00537 
00542 inline void ELIST2_ITERATOR::add_list_before(ELIST2 *list_to_add) {
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 }
00583 
00584 
00592 inline ELIST2_LINK *ELIST2_ITERATOR::extract() {
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 }
00630 
00631 
00637 inline ELIST2_LINK *ELIST2_ITERATOR::move_to_first() {
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 }
00650 
00651 
00657 inline ELIST2_LINK *ELIST2_ITERATOR::move_to_last() {
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 }
00670 
00671 
00680 inline void ELIST2_ITERATOR::mark_cycle_pt() {
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 }
00694 
00695 
00699 inline BOOL8 ELIST2_ITERATOR::at_first() {
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 }
00712 
00713 
00717 inline BOOL8 ELIST2_ITERATOR::at_last() {
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 }
00730 
00731 
00735 inline BOOL8 ELIST2_ITERATOR::cycled_list() {
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 }
00746 
00747 
00751 inline INT32 ELIST2_ITERATOR::length() {
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 }
00761 
00762 
00766 inline void
00767 ELIST2_ITERATOR::sort (          //sort elements
00768 int comparator (                 //comparison routine
00769 const void *, const void *)) {
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 }
00780 
00781 
00789 inline void ELIST2_ITERATOR::add_to_end(  // element to add
00790                                         ELIST2_LINK *new_element) {
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 }
00820 
00821 
00822 /* ========================== */
00823 
00828 #define QUOTE_IT( parm ) #parm
00829 
00875 #define ELIST2IZEH_A( CLASSNAME )                                 \
00876                                                          \
00877 extern DLLSYM void         CLASSNAME##_zapper(        /*delete a link*/ \
00878 ELIST2_LINK*            link);                  /*link to delete*/  \
00879                                                          \
00880 extern DLLSYM ELIST2_LINK* CLASSNAME##_copier(        /*deep copy a link*/\
00881 ELIST2_LINK*            old_element);   /*source link */
00882 
00883 /* ================== */
00884 
00885 #define ELIST2IZEH_B( CLASSNAME )                                 \
00886                                                          \
00887 /***********************************************************************   \
00888 *                    CLASS - CLASSNAME##_LIST                  \
00889 *                                                        \
00890 *                    List class for class CLASSNAME               \
00891 *                                                        \
00892 **********************************************************************/    \
00893                                                          \
00894 class DLLSYM            CLASSNAME##_LIST : public ELIST2          \
00895 {                                                        \
00896 public:                                                     \
00897                      CLASSNAME##_LIST():ELIST2() {}               \
00898                                           /* constructor */ \
00899                                                          \
00900                      CLASSNAME##_LIST(       /* dont construct */\
00901    const CLASSNAME##_LIST&)                     /*by initial assign*/\
00902    { DONT_CONSTRUCT_LIST_BY_COPY.error( QUOTE_IT( CLASSNAME##_LIST ),      \
00903                                           ABORT, NULL ); }  \
00904                                                          \
00905 void                 clear()                 /* delete elements */\
00906    { ELIST2::internal_clear( &CLASSNAME##_zapper ); }                \
00907                                                          \
00908                      ~CLASSNAME##_LIST()  /* destructor */        \
00909    { clear(); }                                             \
00910                                                          \
00911 void                 deep_copy(              /* become a deep */ \
00912    const CLASSNAME##_LIST* list)                /* copy of src list*/\
00913    { ELIST2::internal_deep_copy( &CLASSNAME##_copier, list ); }         \
00914                                                          \
00915 void                 operator=(              /* prevent assign */\
00916    const CLASSNAME##_LIST&)                                    \
00917    { DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_LIST ),          \
00918                                  ABORT, NULL ); }
00919 
00920 /* ================== */
00921 
00922 #define ELIST2IZEH_C( CLASSNAME )                                 \
00923 };                                                       \
00924                                                          \
00925                                                          \
00926                                                          \
00927 /***********************************************************************   \
00928 *                    CLASS - CLASSNAME##_IT                    \
00929 *                                                        \
00930 *                    Iterator class for class CLASSNAME##_LIST    \
00931 *                                                        \
00932 *  Note: We don't need to coerce pointers to member functions input        \
00933 *  parameters as these are automatically converted to the type of the base \
00934 *  type. ("A ptr to a class may be converted to a pointer to a public base \
00935 *  class of that class")                                       \
00936 **********************************************************************/    \
00937                                                          \
00938 class DLLSYM            CLASSNAME##_IT : public ELIST2_ITERATOR         \
00939 {                                                        \
00940 public:                                                     \
00941                         CLASSNAME##_IT():ELIST2_ITERATOR(){}      \
00942                                                          \
00943                         CLASSNAME##_IT(                        \
00944 CLASSNAME##_LIST*       list):ELIST2_ITERATOR(list){}             \
00945                                                          \
00946    CLASSNAME*        data()                                    \
00947       { return (CLASSNAME*) ELIST2_ITERATOR::data(); }               \
00948                                                          \
00949    CLASSNAME*        data_relative(                            \
00950    INT8              offset)                                \
00951       { return (CLASSNAME*) ELIST2_ITERATOR::data_relative( offset ); } \
00952                                                          \
00953    CLASSNAME*        forward()                                 \
00954       { return (CLASSNAME*) ELIST2_ITERATOR::forward(); }               \
00955                                                          \
00956    CLASSNAME*        backward()                                \
00957       { return (CLASSNAME*) ELIST2_ITERATOR::backward(); }           \
00958                                                          \
00959    CLASSNAME*        extract()                                 \
00960       { return (CLASSNAME*) ELIST2_ITERATOR::extract(); }               \
00961                                                          \
00962    CLASSNAME*        move_to_first()                              \
00963       { return (CLASSNAME*) ELIST2_ITERATOR::move_to_first(); }         \
00964                                                          \
00965    CLASSNAME*        move_to_last()                            \
00966       { return (CLASSNAME*) ELIST2_ITERATOR::move_to_last(); }       \
00967 };
00968 
00969 /* ========================== */
00970 
00971 #define ELIST2IZEH( CLASSNAME )                                   \
00972                                                          \
00973 ELIST2IZEH_A( CLASSNAME )                                      \
00974                                                          \
00975 ELIST2IZEH_B( CLASSNAME )                                      \
00976                                                          \
00977 ELIST2IZEH_C( CLASSNAME )
00978 
00979 /* ================== */
00980 
00981 #define ELIST2IZEH_S( CLASSNAME )                                 \
00982                                                          \
00983 ELIST2IZEH_A( CLASSNAME )                                      \
00984                                                          \
00985 extern DLLSYM void         CLASSNAME##_serialiser(                   \
00986 FILE*                f,                                  \
00987 ELIST2_LINK*            element);                              \
00988                                                          \
00989 extern DLLSYM ELIST2_LINK* CLASSNAME##_de_serialiser(                \
00990 FILE*                f);                                    \
00991                                                          \
00992 ELIST2IZEH_B( CLASSNAME )                                      \
00993                                                          \
00994    void              dump(                /* dump to file */  \
00995    FILE*             f)                                  \
00996    { ELIST2::internal_dump( f, &CLASSNAME##_serialiser );}              \
00997                                                          \
00998    void              de_dump(             /* get from file */ \
00999    FILE*             f)                                  \
01000    { ELIST2::internal_de_dump( f, &CLASSNAME##_de_serialiser );}        \
01001                                                          \
01002 make_serialise( CLASSNAME##_LIST )                                \
01003                                                          \
01004 ELIST2IZEH_C( CLASSNAME )
01005 
01006 /* ================== */
01007 
01013 #define ELIST2IZE( CLASSNAME )                                              \
01014                                                          \
01015 /***********************************************************************   \
01016 *                    CLASSNAME##_zapper                        \
01017 *                                                        \
01018 *  A function which can delete a CLASSNAME element.  This is passed to the \
01019 *  generic clear list member function so that when a list is cleared the   \
01020 *  elements on the list are properly destroyed from the base class, even   \
01021 *  though we dont use a virtual destructor function.                 \
01022 **********************************************************************/    \
01023                                                          \
01024 DLLSYM void             CLASSNAME##_zapper(        /*delete a link*/ \
01025 ELIST2_LINK*            link)                /*link to delete*/   \
01026 {                                                        \
01027 delete (CLASSNAME *) link;                                     \
01028 }                                                        \
01029                                                          \
01030                                                          \
01031                                                          \
01032 /***********************************************************************   \
01033 *                    CLASSNAME##_copier                        \
01034 *                                                        \
01035 *  A function which can generate a new, deep copy of a CLASSNAME element.  \
01036 *  This is passed to the generic deep copy list member function so that when\
01037 *  a list is copied the elements on the list are properly copied from the  \
01038 *  base class, even though we dont use a virtual function.              \
01039 **********************************************************************/    \
01040                                                          \
01041 DLLSYM ELIST2_LINK*        CLASSNAME##_copier(        /*deep copy a link*/\
01042 ELIST2_LINK*            old_element)            /*source link*/      \
01043 {                                                        \
01044    CLASSNAME*        new_element;                              \
01045                                                          \
01046 new_element = new CLASSNAME;                                   \
01047 *new_element = *((CLASSNAME*) old_element);                          \
01048 return (ELIST2_LINK*) new_element;                                \
01049 }
01050 
01051 /* ========================== */
01052 
01053 #define ELIST2IZE_S( CLASSNAME )                               \
01054                                                          \
01055 ELIST2IZE( CLASSNAME )                                         \
01056                                                          \
01057 /***********************************************************************   \
01058 *                    CLASSNAME##_serialiser                    \
01059 *                                                        \
01060 *  A function which can serialise an element                      \
01061 *  This is passed to the generic dump member function so that when a list is\
01062 *  serialised the elements on the list are properly serialised.            \
01063 **********************************************************************/    \
01064                                                          \
01065 DLLSYM void             CLASSNAME##_serialiser(                   \
01066 FILE*                f,                                  \
01067 ELIST2_LINK*            element)                            \
01068 {                                                        \
01069 ((CLASSNAME*) element)->serialise( f );                              \
01070 }                                                        \
01071                                                          \
01072                                                          \
01073                                                          \
01074 /***********************************************************************   \
01075 *                    CLASSNAME##_de_serialiser                 \
01076 *                                                        \
01077 *  A function which can de-serialise an element                      \
01078 *  This is passed to the generic de-dump member function so that when a list\
01079 *  is de-serialised the elements on the list are properly de-serialised.   \
01080 **********************************************************************/    \
01081                                                          \
01082 DLLSYM ELIST2_LINK*        CLASSNAME##_de_serialiser(                \
01083 FILE*                f)                                  \
01084 {                                                        \
01085 return (ELIST2_LINK*) CLASSNAME::de_serialise( f );                     \
01086 }
01087 #endif

Generated on Wed Feb 28 19:49:09 2007 for Tesseract by  doxygen 1.5.1