ccutil/elst.h

Go to the documentation of this file.
00001 
00020 #ifndef ELST_H
00021 #define ELST_H
00022 
00023 #include <stdio.h>
00024 #include "host.h"
00025 #include "serialis.h"
00026 #include "lsterr.h"
00027 
00028 class ELIST_ITERATOR;
00078 class DLLSYM ELIST_LINK
00079 {
00080   friend class ELIST_ITERATOR;
00081   friend class ELIST;
00082 
00083   ELIST_LINK *next;
00084 
00085   public:
00086     ELIST_LINK() {
00087       next = NULL;
00088     }
00089     //constructor
00090 
00091     ELIST_LINK(                       //copy constructor
00092                const ELIST_LINK &) {  //dont copy link
00093       next = NULL;
00094     }
00095 
00096     void operator= (             //dont copy links
00097     const ELIST_LINK &) {
00098       next = NULL;
00099     }
00100 
00101     void serialise_asc(  //serialise to ascii
00102                        FILE *f);
00103     void de_serialise_asc(  //de-serialise from ascii
00104                           FILE *f);
00105 
00106 };
00107 
00117 class DLLSYM ELIST
00118 {
00119   friend class ELIST_ITERATOR;
00120 
00121   ELIST_LINK *last;              //End of list
00122   //(Points to head)
00123   ELIST_LINK *First() {  // return first
00124     return last ? last->next : NULL;
00125   }
00126 
00127   public:
00128     ELIST() {  //constructor
00129       last = NULL;
00130     }
00131 
00132     void internal_clear (        //destroy all links
00133                                  //ptr to zapper functn
00134       void (*zapper) (ELIST_LINK *));
00135 
00136     BOOL8 empty() {  //is list empty?
00137       return !last;
00138     }
00139 
00140     BOOL8 singleton() {
00141       return last ? (last == last->next) : FALSE;
00142     }
00143 
00144     void shallow_copy(                     //dangerous!!
00145                       ELIST *from_list) {  //beware destructors!!
00146       last = from_list->last;
00147     }
00148 
00149                                  //ptr to copier functn
00150     void internal_deep_copy (ELIST_LINK * (*copier) (ELIST_LINK *),
00151       const ELIST * list);       //list being copied
00152 
00153     void assign_to_sublist(                           //to this list
00154                            ELIST_ITERATOR *start_it,  //from list start
00155                            ELIST_ITERATOR *end_it);   //from list end
00156 
00157     INT32 length();  //# elements in list
00158 
00159     void sort (                  //sort elements
00160       int comparator (           //comparison routine
00161       const void *, const void *));
00162 
00163     void internal_dump (         //serialise each elem
00164       FILE * f,                  //to this file
00165       void element_serialiser (  //using this function
00166       FILE *, ELIST_LINK *));
00167 
00168     void internal_de_dump (      //de_serial each elem
00169       FILE * f,                  //from this file
00170                                  //using this function
00171       ELIST_LINK * element_de_serialiser (
00172       FILE *));
00173 
00174     void prep_serialise();  //change last to count
00175 
00176 };
00177 
00182 class DLLSYM ELIST_ITERATOR
00183 {
00184   friend void ELIST::assign_to_sublist(ELIST_ITERATOR *, ELIST_ITERATOR *);
00185 
00186   ELIST *list;                   //List being iterated
00187   ELIST_LINK *prev;              //prev element
00188   ELIST_LINK *current;           //current element
00189   ELIST_LINK *next;              //next element
00190   BOOL8 ex_current_was_last;     //current extracted
00191   //was end of list
00192   BOOL8 ex_current_was_cycle_pt; //current extracted
00193   //was cycle point
00194   ELIST_LINK *cycle_pt;          //point we are cycling
00195   //the list to.
00196   BOOL8 started_cycling;         //Have we moved off
00197   //the start?
00198 
00199   ELIST_LINK *extract_sublist(                            //from this current...
00200                               ELIST_ITERATOR *other_it);  //to other current
00201 
00202   public:
00203     ELIST_ITERATOR() {  //constructor
00204       list = NULL;
00205     }                            //unassigned list
00206 
00207     ELIST_ITERATOR(  //constructor
00208                    ELIST *list_to_iterate);
00209 
00210     void set_to_list(  //change list
00211                      ELIST *list_to_iterate);
00212 
00213     void add_after_then_move(                        //add after current &
00214                              ELIST_LINK *new_link);  //move to new
00215 
00216     void add_after_stay_put(                        //add after current &
00217                             ELIST_LINK *new_link);  //stay at current
00218 
00219     void add_before_then_move(                        //add before current &
00220                               ELIST_LINK *new_link);  //move to new
00221 
00222     void add_before_stay_put(                        //add before current &
00223                              ELIST_LINK *new_link);  //stay at current
00224 
00225     void add_list_after(                      //add a list &
00226                         ELIST *list_to_add);  //stay at current
00227 
00228     void add_list_before(                      //add a list &
00229                          ELIST *list_to_add);  //move to it 1st item
00230 
00231     ELIST_LINK *data() {  //get current data
00232     #ifdef _DEBUG
00233       if (!list)
00234         NO_LIST.error ("ELIST_ITERATOR::data", ABORT, NULL);
00235       if (!current)
00236         NULL_DATA.error ("ELIST_ITERATOR::data", ABORT, NULL);
00237     #endif
00238       return current;
00239     }
00240 
00241     ELIST_LINK *data_relative(               //get data + or - ...
00242                               INT8 offset);  //offset from current
00243 
00244     ELIST_LINK *forward();  //move to next element
00245 
00246     ELIST_LINK *extract();  //remove from list
00247 
00248     ELIST_LINK *move_to_first();  //go to start of list
00249 
00250     ELIST_LINK *move_to_last();  //go to end of list
00251 
00252     void mark_cycle_pt();  //remember current
00253 
00254     BOOL8 empty() {  //is list empty?
00255     #ifdef _DEBUG
00256       if (!list)
00257         NO_LIST.error ("ELIST_ITERATOR::empty", ABORT, NULL);
00258     #endif
00259       return list->empty ();
00260     }
00261 
00262     BOOL8 current_extracted() {  //current extracted?
00263       return !current;
00264     }
00265 
00266     BOOL8 at_first();  //Current is first?
00267 
00268     BOOL8 at_last();  //Current is last?
00269 
00270     BOOL8 cycled_list();  //Completed a cycle?
00271 
00272     void add_to_end(                        //add at end &
00273                     ELIST_LINK *new_link);  //dont move
00274 
00275     void exchange(                            //positions of 2 links
00276                   ELIST_ITERATOR *other_it);  //other iterator
00277 
00278     INT32 length();  //# elements in list
00279 
00280     void sort (                  //sort elements
00281       int comparator (           //comparison routine
00282       const void *, const void *));
00283 
00284 };
00285 
00289 inline void ELIST_ITERATOR::set_to_list(  //change list
00290                                         ELIST *list_to_iterate) {
00291   #ifdef _DEBUG
00292   if (!this)
00293     NULL_OBJECT.error ("ELIST_ITERATOR::set_to_list", ABORT, NULL);
00294   if (!list_to_iterate)
00295     BAD_PARAMETER.error ("ELIST_ITERATOR::set_to_list", ABORT,
00296       "list_to_iterate is NULL");
00297   #endif
00298 
00299   list = list_to_iterate;
00300   prev = list->last;
00301   current = list->First ();
00302   next = current ? current->next : NULL;
00303   cycle_pt = NULL;               //await explicit set
00304   started_cycling = FALSE;
00305   ex_current_was_last = FALSE;
00306   ex_current_was_cycle_pt = FALSE;
00307 }
00308 
00309 
00313 inline ELIST_ITERATOR::ELIST_ITERATOR(ELIST *list_to_iterate) {
00314   set_to_list(list_to_iterate);
00315 }
00316 
00317 
00322 inline void ELIST_ITERATOR::add_after_then_move(  // element to add
00323                                                 ELIST_LINK *new_element) {
00324   #ifdef _DEBUG
00325   if (!this)
00326     NULL_OBJECT.error ("ELIST_ITERATOR::add_after_then_move", ABORT, NULL);
00327   if (!list)
00328     NO_LIST.error ("ELIST_ITERATOR::add_after_then_move", ABORT, NULL);
00329   if (!new_element)
00330     BAD_PARAMETER.error ("ELIST_ITERATOR::add_after_then_move", ABORT,
00331       "new_element is NULL");
00332   if (new_element->next)
00333     STILL_LINKED.error ("ELIST_ITERATOR::add_after_then_move", ABORT, NULL);
00334   #endif
00335 
00336   if (list->empty ()) {
00337     new_element->next = new_element;
00338     list->last = new_element;
00339     prev = next = new_element;
00340   }
00341   else {
00342     new_element->next = next;
00343 
00344     if (current) {               //not extracted
00345       current->next = new_element;
00346       prev = current;
00347       if (current == list->last)
00348         list->last = new_element;
00349     }
00350     else {                       //current extracted
00351       prev->next = new_element;
00352       if (ex_current_was_last)
00353         list->last = new_element;
00354       if (ex_current_was_cycle_pt)
00355         cycle_pt = new_element;
00356     }
00357   }
00358   current = new_element;
00359 }
00360 
00361 
00366 inline void ELIST_ITERATOR::add_after_stay_put(  // element to add
00367                                                ELIST_LINK *new_element) {
00368   #ifdef _DEBUG
00369   if (!this)
00370     NULL_OBJECT.error ("ELIST_ITERATOR::add_after_stay_put", ABORT, NULL);
00371   if (!list)
00372     NO_LIST.error ("ELIST_ITERATOR::add_after_stay_put", ABORT, NULL);
00373   if (!new_element)
00374     BAD_PARAMETER.error ("ELIST_ITERATOR::add_after_stay_put", ABORT,
00375       "new_element is NULL");
00376   if (new_element->next)
00377     STILL_LINKED.error ("ELIST_ITERATOR::add_after_stay_put", ABORT, NULL);
00378   #endif
00379 
00380   if (list->empty ()) {
00381     new_element->next = new_element;
00382     list->last = new_element;
00383     prev = next = new_element;
00384     ex_current_was_last = FALSE;
00385     current = NULL;
00386   }
00387   else {
00388     new_element->next = next;
00389 
00390     if (current) {               //not extracted
00391       current->next = new_element;
00392       if (prev == current)
00393         prev = new_element;
00394       if (current == list->last)
00395         list->last = new_element;
00396     }
00397     else {                       //current extracted
00398       prev->next = new_element;
00399       if (ex_current_was_last) {
00400         list->last = new_element;
00401         ex_current_was_last = FALSE;
00402       }
00403     }
00404     next = new_element;
00405   }
00406 }
00407 
00408 
00413 inline void ELIST_ITERATOR::add_before_then_move(  // element to add
00414                                                  ELIST_LINK *new_element) {
00415   #ifdef _DEBUG
00416   if (!this)
00417     NULL_OBJECT.error ("ELIST_ITERATOR::add_before_then_move", ABORT, NULL);
00418   if (!list)
00419     NO_LIST.error ("ELIST_ITERATOR::add_before_then_move", ABORT, NULL);
00420   if (!new_element)
00421     BAD_PARAMETER.error ("ELIST_ITERATOR::add_before_then_move", ABORT,
00422       "new_element is NULL");
00423   if (new_element->next)
00424     STILL_LINKED.error ("ELIST_ITERATOR::add_before_then_move", ABORT, NULL);
00425   #endif
00426 
00427   if (list->empty ()) {
00428     new_element->next = new_element;
00429     list->last = new_element;
00430     prev = next = new_element;
00431   }
00432   else {
00433     prev->next = new_element;
00434     if (current) {               //not extracted
00435       new_element->next = current;
00436       next = current;
00437     }
00438     else {                       //current extracted
00439       new_element->next = next;
00440       if (ex_current_was_last)
00441         list->last = new_element;
00442       if (ex_current_was_cycle_pt)
00443         cycle_pt = new_element;
00444     }
00445   }
00446   current = new_element;
00447 }
00448 
00449 
00454 inline void ELIST_ITERATOR::add_before_stay_put(  // element to add
00455                                                 ELIST_LINK *new_element) {
00456   #ifdef _DEBUG
00457   if (!this)
00458     NULL_OBJECT.error ("ELIST_ITERATOR::add_before_stay_put", ABORT, NULL);
00459   if (!list)
00460     NO_LIST.error ("ELIST_ITERATOR::add_before_stay_put", ABORT, NULL);
00461   if (!new_element)
00462     BAD_PARAMETER.error ("ELIST_ITERATOR::add_before_stay_put", ABORT,
00463       "new_element is NULL");
00464   if (new_element->next)
00465     STILL_LINKED.error ("ELIST_ITERATOR::add_before_stay_put", ABORT, NULL);
00466   #endif
00467 
00468   if (list->empty ()) {
00469     new_element->next = new_element;
00470     list->last = new_element;
00471     prev = next = new_element;
00472     ex_current_was_last = TRUE;
00473     current = NULL;
00474   }
00475   else {
00476     prev->next = new_element;
00477     if (current) {               //not extracted
00478       new_element->next = current;
00479       if (next == current)
00480         next = new_element;
00481     }
00482     else {                       //current extracted
00483       new_element->next = next;
00484       if (ex_current_was_last)
00485         list->last = new_element;
00486     }
00487     prev = new_element;
00488   }
00489 }
00490 
00491 
00495 inline void ELIST_ITERATOR::add_list_after(ELIST *list_to_add) {
00496   #ifdef _DEBUG
00497   if (!this)
00498     NULL_OBJECT.error ("ELIST_ITERATOR::add_list_after", ABORT, NULL);
00499   if (!list)
00500     NO_LIST.error ("ELIST_ITERATOR::add_list_after", ABORT, NULL);
00501   if (!list_to_add)
00502     BAD_PARAMETER.error ("ELIST_ITERATOR::add_list_after", ABORT,
00503       "list_to_add is NULL");
00504   #endif
00505 
00506   if (!list_to_add->empty ()) {
00507     if (list->empty ()) {
00508       list->last = list_to_add->last;
00509       prev = list->last;
00510       next = list->First ();
00511       ex_current_was_last = TRUE;
00512       current = NULL;
00513     }
00514     else {
00515       if (current) {             //not extracted
00516         current->next = list_to_add->First ();
00517         if (current == list->last)
00518           list->last = list_to_add->last;
00519         list_to_add->last->next = next;
00520         next = current->next;
00521       }
00522       else {                     //current extracted
00523         prev->next = list_to_add->First ();
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->next;
00530       }
00531     }
00532     list_to_add->last = NULL;
00533   }
00534 }
00535 
00536 
00542 inline void ELIST_ITERATOR::add_list_before(ELIST *list_to_add) {
00543   #ifdef _DEBUG
00544   if (!this)
00545     NULL_OBJECT.error ("ELIST_ITERATOR::add_list_before", ABORT, NULL);
00546   if (!list)
00547     NO_LIST.error ("ELIST_ITERATOR::add_list_before", ABORT, NULL);
00548   if (!list_to_add)
00549     BAD_PARAMETER.error ("ELIST_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       if (current) {             //not extracted
00564         list_to_add->last->next = current;
00565       }
00566       else {                     //current extracted
00567         list_to_add->last->next = next;
00568         if (ex_current_was_last)
00569           list->last = list_to_add->last;
00570         if (ex_current_was_cycle_pt)
00571           cycle_pt = prev->next;
00572       }
00573       current = prev->next;
00574       next = current->next;
00575     }
00576     list_to_add->last = NULL;
00577   }
00578 }
00579 
00580 
00588 inline ELIST_LINK *ELIST_ITERATOR::extract() {
00589   ELIST_LINK *extracted_link;
00590 
00591   #ifdef _DEBUG
00592   if (!this)
00593     NULL_OBJECT.error ("ELIST_ITERATOR::extract", ABORT, NULL);
00594   if (!list)
00595     NO_LIST.error ("ELIST_ITERATOR::extract", ABORT, NULL);
00596   if (!current)                  //list empty or
00597                                  //element extracted
00598     NULL_CURRENT.error ("ELIST_ITERATOR::extract",
00599       ABORT, NULL);
00600   #endif
00601 
00602   if (list->singleton ())        //special case where
00603                                  //we do need to
00604     prev = next = list->last = NULL;
00605   //      change the iterator
00606   else {
00607     prev->next = next;           //remove from list
00608 
00609     if (current == list->last) {
00610       list->last = prev;
00611       ex_current_was_last = TRUE;
00612     }
00613     else
00614       ex_current_was_last = FALSE;
00615 
00616     ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
00617 
00618   }
00619   extracted_link = current;
00620   extracted_link->next = NULL;   //for safety
00621   current = NULL;
00622   return extracted_link;
00623 }
00624 
00625 
00631 inline ELIST_LINK *ELIST_ITERATOR::move_to_first() {
00632   #ifdef _DEBUG
00633   if (!this)
00634     NULL_OBJECT.error ("ELIST_ITERATOR::move_to_first", ABORT, NULL);
00635   if (!list)
00636     NO_LIST.error ("ELIST_ITERATOR::move_to_first", ABORT, NULL);
00637   #endif
00638 
00639   current = list->First ();
00640   prev = list->last;
00641   next = current ? current->next : NULL;
00642   return current;
00643 }
00644 
00645 
00654 inline void ELIST_ITERATOR::mark_cycle_pt() {
00655   #ifdef _DEBUG
00656   if (!this)
00657     NULL_OBJECT.error ("ELIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
00658   if (!list)
00659     NO_LIST.error ("ELIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
00660   #endif
00661 
00662   if (current)
00663     cycle_pt = current;
00664   else
00665     ex_current_was_cycle_pt = TRUE;
00666   started_cycling = FALSE;
00667 }
00668 
00669 
00673 inline BOOL8 ELIST_ITERATOR::at_first() {
00674   #ifdef _DEBUG
00675   if (!this)
00676     NULL_OBJECT.error ("ELIST_ITERATOR::at_first", ABORT, NULL);
00677   if (!list)
00678     NO_LIST.error ("ELIST_ITERATOR::at_first", ABORT, NULL);
00679   #endif
00680 
00681                                  //we're at a deleted
00682   return ((list->empty ()) || (current == list->First ()) || ((current == NULL) &&
00683     (prev == list->last) &&      //NON-last pt between
00684     !ex_current_was_last));      //first and last
00685 }
00686 
00687 
00691 inline BOOL8 ELIST_ITERATOR::at_last() {
00692   #ifdef _DEBUG
00693   if (!this)
00694     NULL_OBJECT.error ("ELIST_ITERATOR::at_last", ABORT, NULL);
00695   if (!list)
00696     NO_LIST.error ("ELIST_ITERATOR::at_last", ABORT, NULL);
00697   #endif
00698 
00699                                  //we're at a deleted
00700   return ((list->empty ()) || (current == list->last) || ((current == NULL) &&
00701     (prev == list->last) &&      //last point between
00702     ex_current_was_last));       //first and last
00703 }
00704 
00705 
00709 inline BOOL8 ELIST_ITERATOR::cycled_list() {
00710   #ifdef _DEBUG
00711   if (!this)
00712     NULL_OBJECT.error ("ELIST_ITERATOR::cycled_list", ABORT, NULL);
00713   if (!list)
00714     NO_LIST.error ("ELIST_ITERATOR::cycled_list", ABORT, NULL);
00715   #endif
00716 
00717   return ((list->empty ()) || ((current == cycle_pt) && started_cycling));
00718 
00719 }
00720 
00721 
00725 inline INT32 ELIST_ITERATOR::length() {
00726   #ifdef _DEBUG
00727   if (!this)
00728     NULL_OBJECT.error ("ELIST_ITERATOR::length", ABORT, NULL);
00729   if (!list)
00730     NO_LIST.error ("ELIST_ITERATOR::length", ABORT, NULL);
00731   #endif
00732 
00733   return list->length ();
00734 }
00735 
00736 
00740 inline void
00741 ELIST_ITERATOR::sort (           //sort elements
00742 int comparator (                 //comparison routine
00743 const void *, const void *)) {
00744   #ifdef _DEBUG
00745   if (!this)
00746     NULL_OBJECT.error ("ELIST_ITERATOR::sort", ABORT, NULL);
00747   if (!list)
00748     NO_LIST.error ("ELIST_ITERATOR::sort", ABORT, NULL);
00749   #endif
00750 
00751   list->sort (comparator);
00752   move_to_first();
00753 }
00754 
00755 
00763 inline void ELIST_ITERATOR::add_to_end(  // element to add
00764                                        ELIST_LINK *new_element) {
00765   #ifdef _DEBUG
00766   if (!this)
00767     NULL_OBJECT.error ("ELIST_ITERATOR::add_to_end", ABORT, NULL);
00768   if (!list)
00769     NO_LIST.error ("ELIST_ITERATOR::add_to_end", ABORT, NULL);
00770   if (!new_element)
00771     BAD_PARAMETER.error ("ELIST_ITERATOR::add_to_end", ABORT,
00772       "new_element is NULL");
00773   if (new_element->next)
00774     STILL_LINKED.error ("ELIST_ITERATOR::add_to_end", ABORT, NULL);
00775   #endif
00776 
00777   if (this->at_last ()) {
00778     this->add_after_stay_put (new_element);
00779   }
00780   else {
00781     if (this->at_first ()) {
00782       this->add_before_stay_put (new_element);
00783       list->last = new_element;
00784     }
00785     else {                       //Iteratr is elsewhere
00786       new_element->next = list->last->next;
00787       list->last->next = new_element;
00788       list->last = new_element;
00789     }
00790   }
00791 }
00792 
00793 
00794 /* ********************    MACROS    *************************/
00795 
00800 #define QUOTE_IT( parm ) #parm
00801 
00909 #define ELISTIZEH_A( CLASSNAME )                               \
00910                                                          \
00911 extern DLLSYM void         CLASSNAME##_zapper(        /*delete a link*/ \
00912 ELIST_LINK*             link);                  /*link to delete*/  \
00913                                                          \
00914 extern DLLSYM ELIST_LINK*  CLASSNAME##_copier(        /*deep copy a link*/\
00915 ELIST_LINK*             old_element);   /*source link */
00916 
00917 /* ================= */
00918 
00919 #define ELISTIZEH_B( CLASSNAME )                               \
00920                                                          \
00921 /***********************************************************************   \
00922 *                    CLASS - CLASSNAME##_LIST                  \
00923 *                                                        \
00924 *                    List class for class CLASSNAME               \
00925 *                                                        \
00926 **********************************************************************/    \
00927                                                          \
00928 class DLLSYM            CLASSNAME##_LIST : public ELIST              \
00929 {                                                     \
00930 public:                                                  \
00931                      CLASSNAME##_LIST():ELIST() {}               \
00932                         /* constructor */                \
00933                                                       \
00934                      CLASSNAME##_LIST( /* dont construct */    \
00935    const CLASSNAME##_LIST&)               /*by initial assign*/   \
00936    { DONT_CONSTRUCT_LIST_BY_COPY.error( QUOTE_IT( CLASSNAME##_LIST ),  \
00937                                           ABORT, NULL ); }\
00938                                                       \
00939 void                 clear()           /* delete elements */\
00940    { ELIST::internal_clear( &CLASSNAME##_zapper ); }           \
00941                                                    \
00942                      ~CLASSNAME##_LIST()  /* destructor */  \
00943    { clear(); }                                       \
00944                                                    \
00945 void                 deep_copy(        /* become a deep */  \
00946    const CLASSNAME##_LIST* list)          /* copy of src list*/\
00947    { ELIST::internal_deep_copy( &CLASSNAME##_copier, list ); }    \
00948                                                    \
00949 void                 operator=(        /* prevent assign */\
00950    const CLASSNAME##_LIST&)                              \
00951    { DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_LIST ),    \
00952                                  ABORT, NULL ); }
00953 
00954 /* ================= */
00955 
00956 #define ELISTIZEH_C( CLASSNAME )                         \
00957 };                                                 \
00958                                                    \
00959                                                    \
00960                                                    \
00961 /**************************************************************      \
00962 *                    CLASS - CLASSNAME##_IT              \
00963 *                                                  \
00964 *                 Iterator class for class CLASSNAME##_LIST \
00965 *                                                  \
00966 *  Note: We don't need to coerce pointers to member functions input  \
00967 *  parameters as these are automatically converted to the type of the base\
00968 *  type. ("A ptr to a class may be converted to a pointer to a public base\
00969 *  class of that class")                                 \
00970 ******************************************************************/  \
00971                                                    \
00972 class DLLSYM            CLASSNAME##_IT : public ELIST_ITERATOR \
00973 {                                                  \
00974 public:                                               \
00975                         CLASSNAME##_IT():ELIST_ITERATOR(){} \
00976                                                    \
00977                         CLASSNAME##_IT(                  \
00978 CLASSNAME##_LIST*       list):ELIST_ITERATOR(list){}        \
00979                                                    \
00980    CLASSNAME*        data()                              \
00981       { return (CLASSNAME*) ELIST_ITERATOR::data(); }          \
00982                                                    \
00983    CLASSNAME*        data_relative(                      \
00984    INT8              offset)                          \
00985       { return (CLASSNAME*) ELIST_ITERATOR::data_relative( offset ); }\
00986                                                    \
00987    CLASSNAME*        forward()                           \
00988       { return (CLASSNAME*) ELIST_ITERATOR::forward(); }       \
00989                                                    \
00990    CLASSNAME*        extract()                           \
00991       { return (CLASSNAME*) ELIST_ITERATOR::extract(); }       \
00992                                                    \
00993    CLASSNAME*        move_to_first()                        \
00994       { return (CLASSNAME*) ELIST_ITERATOR::move_to_first(); } \
00995                                                    \
00996    CLASSNAME*        move_to_last()                      \
00997       { return (CLASSNAME*) ELIST_ITERATOR::move_to_last(); }     \
00998 };
00999 
01000 /* ================= */
01001 
01002 #define ELISTIZEH( CLASSNAME )      \
01003                            \
01004 ELISTIZEH_A( CLASSNAME )         \
01005                            \
01006 ELISTIZEH_B( CLASSNAME )         \
01007                            \
01008 ELISTIZEH_C( CLASSNAME )
01009 
01010 /* ================= */
01011 
01012 #define ELISTIZEH_S( CLASSNAME )                   \
01013                                              \
01014 ELISTIZEH_A( CLASSNAME )                           \
01015                                              \
01016 extern DLLSYM void         CLASSNAME##_serialiser(       \
01017 FILE*                f,                      \
01018 ELIST_LINK*             element);                  \
01019                                              \
01020 extern DLLSYM ELIST_LINK*  CLASSNAME##_de_serialiser(    \
01021 FILE*                f);                        \
01022                                              \
01023 ELISTIZEH_B( CLASSNAME )                           \
01024                                              \
01025    void              dump( /* dump to file */         \
01026    FILE*             f)                         \
01027    { ELIST::internal_dump( f, &CLASSNAME##_serialiser );}      \
01028                                                 \
01029    void              de_dump(/* get from file */      \
01030    FILE*             f)                         \
01031    { ELIST::internal_de_dump( f, &CLASSNAME##_de_serialiser );}\
01032                                                 \
01033    void              serialise_asc(/*dump to ascii*/     \
01034    FILE*             f);                           \
01035    void              de_serialise_asc(/*de-dump from ascii*/ \
01036    FILE*             f);                           \
01037                                                 \
01038 make_serialise( CLASSNAME##_LIST )                       \
01039                                                 \
01040 ELISTIZEH_C( CLASSNAME )
01041 
01042 /* ==================
01043   ELISTIZE( CLASSNAME )  and   ELISTIZE_S( CLASSNAME )  MACROS
01044 ELISTIZE_S is a simple extension to ELISTIZE
01045 ***********************************************************************/
01046 
01047 #define ELISTIZE( CLASSNAME )                                            \
01048                                                       \
01049 /*****************************************************************      \
01050 *                    CLASSNAME##_zapper                     \
01051 *                                                     \
01052 *  A function which can delete a CLASSNAME element.  This is passed to the \
01053 *  generic clear list member function so that when a list is cleared the   \
01054 *  elements on the list are properly destroyed from the base class, even   \
01055 *  though we dont use a virtual destructor function.                 \
01056 **********************************************************************/    \
01057                                                          \
01058 DLLSYM void             CLASSNAME##_zapper(     /*delete a link*/ \
01059 ELIST_LINK*             link)             /*link to delete*/   \
01060 {                                                        \
01061 delete (CLASSNAME *) link;                                     \
01062 }                                                        \
01063                                                          \
01064 /***********************************************************************   \
01065 *                    CLASSNAME##_copier                        \
01066 *                                                        \
01067 *  A function which can generate a new, deep copy of a CLASSNAME element.  \
01068 *  This is passed to the generic deep copy list member function so that when\
01069 *  a list is copied the elements on the list are properly copied from the  \
01070 *  base class, even though we dont use a virtual function.              \
01071 **********************************************************************/    \
01072                                                          \
01073 DLLSYM ELIST_LINK*         CLASSNAME##_copier(     /*deep copy a link*/ \
01074 ELIST_LINK*             old_element)         /*source link*/         \
01075 {                                                        \
01076    CLASSNAME*        new_element;                              \
01077                                                          \
01078 new_element = new CLASSNAME;                                   \
01079 *new_element = *((CLASSNAME*) old_element);                          \
01080 return (ELIST_LINK*) new_element;                                 \
01081 }
01082 
01083 /* ================= */
01084 
01085 #define ELISTIZE_S( CLASSNAME )                                   \
01086                                                          \
01087 ELISTIZE( CLASSNAME )                                          \
01088                                                          \
01089    void              CLASSNAME##_LIST::serialise_asc(             \
01090                                     /*dump to ascii*/       \
01091    FILE*             f)                                  \
01092    {                                                     \
01093       CLASSNAME##_IT    it(this);                              \
01094                                                          \
01095       serialise_INT32(f,length());                             \
01096       for (it.mark_cycle_pt();!it.cycled_list();it.forward())           \
01097          it.data()->serialise_asc(f);        /*serialise the list*/  \
01098    }                                                     \
01099                                                          \
01100    void              CLASSNAME##_LIST::de_serialise_asc(          \
01101                                        /*de-dump from ascii*/  \
01102    FILE*             f)                                  \
01103    {                                                     \
01104       INT32          len;           /* length to retrive */    \
01105       CLASSNAME##_IT    it;                                 \
01106       CLASSNAME*     new_elt=NULL;        /*list element*/     \
01107                                                       \
01108       len=de_serialise_INT32(f);                            \
01109       it.set_to_list(this);                                 \
01110       for (;len>0;len--)                                    \
01111       {                                               \
01112          new_elt=new CLASSNAME;                             \
01113          new_elt->de_serialise_asc(f);                      \
01114          it.add_to_end(new_elt);             /*put on the list*/  \
01115       }                                               \
01116       return;                                            \
01117    }                                                  \
01118                                                       \
01119                                                       \
01120 /******************************************************************     \
01121 *                    CLASSNAME##_serialiser                 \
01122 *                                                     \
01123 *  A function which can serialise an element                   \
01124 *  This is passed to the generic dump member function so that when a \
01125 *  list is serialised the elements on the list are properly serialised. \
01126 **********************************************************************/ \
01127                                                       \
01128 DLLSYM void             CLASSNAME##_serialiser(                \
01129 FILE*                f,                               \
01130 ELIST_LINK*             element)                         \
01131 {                                                     \
01132 ((CLASSNAME*) element)->serialise( f );                           \
01133 }                                                     \
01134                                                       \
01135 /****************************************************************    \
01136 *                    CLASSNAME##_de_serialiser              \
01137 *                                                     \
01138 *  A function which can de-serialise an element                   \
01139 *  This is passed to the generic de-dump member function so that when   \
01140 *  a list is de-serialised the elements on the list are properly     \
01141 *  de-serialised.                                        \
01142 ********************************************************************/   \
01143                                                       \
01144 DLLSYM ELIST_LINK*         CLASSNAME##_de_serialiser(             \
01145 FILE*                f)                               \
01146 {                                                     \
01147 return (ELIST_LINK*) CLASSNAME::de_serialise( f );                \
01148 }
01149 #endif

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