tesseract 3.04.01

ccutil/clst.h

Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:        clst.h  (Formerly clist.h)
00003  * Description: CONS cell list module include file.
00004  * Author:      Phil Cheatle
00005  * Created:     Mon Jan 28 08:33:13 GMT 1991
00006  *
00007  * (C) Copyright 1991, Hewlett-Packard Ltd.
00008  ** Licensed under the Apache License, Version 2.0 (the "License");
00009  ** you may not use this file except in compliance with the License.
00010  ** You may obtain a copy of the License at
00011  ** http://www.apache.org/licenses/LICENSE-2.0
00012  ** Unless required by applicable law or agreed to in writing, software
00013  ** distributed under the License is distributed on an "AS IS" BASIS,
00014  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  ** See the License for the specific language governing permissions and
00016  ** limitations under the License.
00017  *
00018  **********************************************************************/
00019 
00020 #ifndef CLST_H
00021 #define CLST_H
00022 
00023 #include <stdio.h>
00024 #include "host.h"
00025 #include "serialis.h"
00026 #include "lsterr.h"
00027 
00028 class CLIST_ITERATOR;
00029 
00030 /**********************************************************************
00031  *                                                      CLASS - CLIST_LINK
00032  *
00033  *                                                      Generic link class for singly linked CONS cell lists
00034  *
00035  *  Note:  No destructor - elements are assumed to be destroyed EITHER after
00036  *  they have been extracted from a list OR by the CLIST destructor which
00037  *  walks the list.
00038  **********************************************************************/
00039 
00040 class DLLSYM CLIST_LINK
00041 {
00042   friend class CLIST_ITERATOR;
00043   friend class CLIST;
00044 
00045   CLIST_LINK *next;
00046   void *data;
00047 
00048   public:
00049     CLIST_LINK() {  //constructor
00050       data = next = NULL;
00051     }
00052 
00053     CLIST_LINK(                       //copy constructor
00054                const CLIST_LINK &) {  //don't copy link
00055       data = next = NULL;
00056     }
00057 
00058     void operator= (             //don't copy links
00059     const CLIST_LINK &) {
00060       data = next = NULL;
00061     }
00062 };
00063 
00064 /**********************************************************************
00065  * CLASS - CLIST
00066  *
00067  * Generic list class for singly linked CONS cell lists
00068  **********************************************************************/
00069 
00070 class DLLSYM CLIST
00071 {
00072   friend class CLIST_ITERATOR;
00073 
00074   CLIST_LINK *last;              //End of list
00075   //(Points to head)
00076   CLIST_LINK *First() {  // return first
00077     return last != NULL ? last->next : NULL;
00078   }
00079 
00080   public:
00081     CLIST() {  //constructor
00082       last = NULL;
00083     }
00084 
00085     ~CLIST () {                  //destructor
00086       shallow_clear();
00087     }
00088 
00089     void internal_deep_clear (   //destroy all links
00090       void (*zapper) (void *));  //ptr to zapper functn
00091 
00092     void shallow_clear();  //clear list but don't
00093     //delete data elements
00094 
00095     bool empty() const {  //is list empty?
00096       return !last;
00097     }
00098 
00099     bool singleton() const {
00100       return last != NULL ? (last == last->next) : false;
00101     }
00102 
00103     void shallow_copy(                     //dangerous!!
00104                       CLIST *from_list) {  //beware destructors!!
00105       last = from_list->last;
00106     }
00107 
00108     void assign_to_sublist(                           //to this list
00109                            CLIST_ITERATOR *start_it,  //from list start
00110                            CLIST_ITERATOR *end_it);   //from list end
00111 
00112     inT32 length() const;  //# elements in list
00113 
00114     void sort (                  //sort elements
00115       int comparator (           //comparison routine
00116       const void *, const void *));
00117 
00118     // Assuming list has been sorted already, insert new_data to
00119     // keep the list sorted according to the same comparison function.
00120     // Comparison function is the same as used by sort, i.e. uses double
00121     // indirection. Time is O(1) to add to beginning or end.
00122     // Time is linear to add pre-sorted items to an empty list.
00123     // If unique, then don't add duplicate entries.
00124     // Returns true if the element was added to the list.
00125     bool add_sorted(int comparator(const void*, const void*),
00126                     bool unique, void* new_data);
00127 
00128     // Assuming that the minuend and subtrahend are already sorted with
00129     // the same comparison function, shallow clears this and then copies
00130     // the set difference minuend - subtrahend to this, being the elements
00131     // of minuend that do not compare equal to anything in subtrahend.
00132     // If unique is true, any duplicates in minuend are also eliminated.
00133     void set_subtract(int comparator(const void*, const void*), bool unique,
00134                       CLIST* minuend, CLIST* subtrahend);
00135 
00136 };
00137 
00138 /***********************************************************************
00139  *                                                      CLASS - CLIST_ITERATOR
00140  *
00141  *                                                      Generic iterator class for singly linked lists with embedded links
00142  **********************************************************************/
00143 
00144 class DLLSYM CLIST_ITERATOR
00145 {
00146   friend void CLIST::assign_to_sublist(CLIST_ITERATOR *, CLIST_ITERATOR *);
00147 
00148   CLIST *list;                   //List being iterated
00149   CLIST_LINK *prev;              //prev element
00150   CLIST_LINK *current;           //current element
00151   CLIST_LINK *next;              //next element
00152   BOOL8 ex_current_was_last;     //current extracted
00153   //was end of list
00154   BOOL8 ex_current_was_cycle_pt; //current extracted
00155   //was cycle point
00156   CLIST_LINK *cycle_pt;          //point we are cycling
00157   //the list to.
00158   BOOL8 started_cycling;         //Have we moved off
00159   //the start?
00160 
00161   CLIST_LINK *extract_sublist(                            //from this current...
00162                               CLIST_ITERATOR *other_it);  //to other current
00163 
00164   public:
00165     CLIST_ITERATOR() {  //constructor
00166       list = NULL;
00167     }                            //unassigned list
00168 
00169     CLIST_ITERATOR(  //constructor
00170                    CLIST *list_to_iterate);
00171 
00172     void set_to_list(  //change list
00173                      CLIST *list_to_iterate);
00174 
00175     void add_after_then_move(                  //add after current &
00176                              void *new_data);  //move to new
00177 
00178     void add_after_stay_put(                  //add after current &
00179                             void *new_data);  //stay at current
00180 
00181     void add_before_then_move(                  //add before current &
00182                               void *new_data);  //move to new
00183 
00184     void add_before_stay_put(                  //add before current &
00185                              void *new_data);  //stay at current
00186 
00187     void add_list_after(                      //add a list &
00188                         CLIST *list_to_add);  //stay at current
00189 
00190     void add_list_before(                      //add a list &
00191                          CLIST *list_to_add);  //move to it 1st item
00192 
00193     void *data() {  //get current data
00194     #ifndef NDEBUG
00195       if (!list)
00196         NO_LIST.error ("CLIST_ITERATOR::data", ABORT, NULL);
00197       if (!current)
00198         NULL_DATA.error ("CLIST_ITERATOR::data", ABORT, NULL);
00199     #endif
00200       return current->data;
00201     }
00202 
00203     void *data_relative(               //get data + or - ...
00204                         inT8 offset);  //offset from current
00205 
00206     void *forward();  //move to next element
00207 
00208     void *extract();  //remove from list
00209 
00210     void *move_to_first();  //go to start of list
00211 
00212     void *move_to_last();  //go to end of list
00213 
00214     void mark_cycle_pt();  //remember current
00215 
00216     BOOL8 empty() {  //is list empty?
00217     #ifndef NDEBUG
00218       if (!list)
00219         NO_LIST.error ("CLIST_ITERATOR::empty", ABORT, NULL);
00220     #endif
00221       return list->empty ();
00222     }
00223 
00224     BOOL8 current_extracted() {  //current extracted?
00225       return !current;
00226     }
00227 
00228     BOOL8 at_first();  //Current is first?
00229 
00230     BOOL8 at_last();  //Current is last?
00231 
00232     BOOL8 cycled_list();  //Completed a cycle?
00233 
00234     void add_to_end(                  //add at end &
00235                     void *new_data);  //don't move
00236 
00237     void exchange(                            //positions of 2 links
00238                   CLIST_ITERATOR *other_it);  //other iterator
00239 
00240     inT32 length();  //# elements in list
00241 
00242     void sort (                  //sort elements
00243       int comparator (           //comparison routine
00244       const void *, const void *));
00245 
00246 };
00247 
00248 /***********************************************************************
00249  *                                                      CLIST_ITERATOR::set_to_list
00250  *
00251  *  (Re-)initialise the iterator to point to the start of the list_to_iterate
00252  *  over.
00253  **********************************************************************/
00254 
00255 inline void CLIST_ITERATOR::set_to_list(  //change list
00256                                         CLIST *list_to_iterate) {
00257   #ifndef NDEBUG
00258   if (!list_to_iterate)
00259     BAD_PARAMETER.error ("CLIST_ITERATOR::set_to_list", ABORT,
00260       "list_to_iterate is NULL");
00261   #endif
00262 
00263   list = list_to_iterate;
00264   prev = list->last;
00265   current = list->First ();
00266   next = current != NULL ? current->next : NULL;
00267   cycle_pt = NULL;               //await explicit set
00268   started_cycling = FALSE;
00269   ex_current_was_last = FALSE;
00270   ex_current_was_cycle_pt = FALSE;
00271 }
00272 
00273 
00274 /***********************************************************************
00275  *                                                      CLIST_ITERATOR::CLIST_ITERATOR
00276  *
00277  *  CONSTRUCTOR - set iterator to specified list;
00278  **********************************************************************/
00279 
00280 inline CLIST_ITERATOR::CLIST_ITERATOR(CLIST *list_to_iterate) {
00281   set_to_list(list_to_iterate);
00282 }
00283 
00284 
00285 /***********************************************************************
00286  *                                                      CLIST_ITERATOR::add_after_then_move
00287  *
00288  *  Add a new element to the list after the current element and move the
00289  *  iterator to the new element.
00290  **********************************************************************/
00291 
00292 inline void CLIST_ITERATOR::add_after_then_move(  // element to add
00293                                                 void *new_data) {
00294   CLIST_LINK *new_element;
00295 
00296   #ifndef NDEBUG
00297   if (!list)
00298     NO_LIST.error ("CLIST_ITERATOR::add_after_then_move", ABORT, NULL);
00299   if (!new_data)
00300     BAD_PARAMETER.error ("CLIST_ITERATOR::add_after_then_move", ABORT,
00301       "new_data is NULL");
00302   #endif
00303 
00304   new_element = new CLIST_LINK;
00305   new_element->data = new_data;
00306 
00307   if (list->empty ()) {
00308     new_element->next = new_element;
00309     list->last = new_element;
00310     prev = next = new_element;
00311   }
00312   else {
00313     new_element->next = next;
00314 
00315     if (current) {               //not extracted
00316       current->next = new_element;
00317       prev = current;
00318       if (current == list->last)
00319         list->last = new_element;
00320     }
00321     else {                       //current extracted
00322       prev->next = new_element;
00323       if (ex_current_was_last)
00324         list->last = new_element;
00325       if (ex_current_was_cycle_pt)
00326         cycle_pt = new_element;
00327     }
00328   }
00329   current = new_element;
00330 }
00331 
00332 
00333 /***********************************************************************
00334  *                                                      CLIST_ITERATOR::add_after_stay_put
00335  *
00336  *  Add a new element to the list after the current element but do not move
00337  *  the iterator to the new element.
00338  **********************************************************************/
00339 
00340 inline void CLIST_ITERATOR::add_after_stay_put(  // element to add
00341                                                void *new_data) {
00342   CLIST_LINK *new_element;
00343 
00344   #ifndef NDEBUG
00345   if (!list)
00346     NO_LIST.error ("CLIST_ITERATOR::add_after_stay_put", ABORT, NULL);
00347   if (!new_data)
00348     BAD_PARAMETER.error ("CLIST_ITERATOR::add_after_stay_put", ABORT,
00349       "new_data is NULL");
00350   #endif
00351 
00352   new_element = new CLIST_LINK;
00353   new_element->data = new_data;
00354 
00355   if (list->empty ()) {
00356     new_element->next = new_element;
00357     list->last = new_element;
00358     prev = next = new_element;
00359     ex_current_was_last = FALSE;
00360     current = NULL;
00361   }
00362   else {
00363     new_element->next = next;
00364 
00365     if (current) {               //not extracted
00366       current->next = new_element;
00367       if (prev == current)
00368         prev = new_element;
00369       if (current == list->last)
00370         list->last = new_element;
00371     }
00372     else {                       //current extracted
00373       prev->next = new_element;
00374       if (ex_current_was_last) {
00375         list->last = new_element;
00376         ex_current_was_last = FALSE;
00377       }
00378     }
00379     next = new_element;
00380   }
00381 }
00382 
00383 
00384 /***********************************************************************
00385  *                                                      CLIST_ITERATOR::add_before_then_move
00386  *
00387  *  Add a new element to the list before the current element and move the
00388  *  iterator to the new element.
00389  **********************************************************************/
00390 
00391 inline void CLIST_ITERATOR::add_before_then_move(  // element to add
00392                                                  void *new_data) {
00393   CLIST_LINK *new_element;
00394 
00395   #ifndef NDEBUG
00396   if (!list)
00397     NO_LIST.error ("CLIST_ITERATOR::add_before_then_move", ABORT, NULL);
00398   if (!new_data)
00399     BAD_PARAMETER.error ("CLIST_ITERATOR::add_before_then_move", ABORT,
00400       "new_data is NULL");
00401   #endif
00402 
00403   new_element = new CLIST_LINK;
00404   new_element->data = new_data;
00405 
00406   if (list->empty ()) {
00407     new_element->next = new_element;
00408     list->last = new_element;
00409     prev = next = new_element;
00410   }
00411   else {
00412     prev->next = new_element;
00413     if (current) {               //not extracted
00414       new_element->next = current;
00415       next = current;
00416     }
00417     else {                       //current extracted
00418       new_element->next = next;
00419       if (ex_current_was_last)
00420         list->last = new_element;
00421       if (ex_current_was_cycle_pt)
00422         cycle_pt = new_element;
00423     }
00424   }
00425   current = new_element;
00426 }
00427 
00428 
00429 /***********************************************************************
00430  *                                                      CLIST_ITERATOR::add_before_stay_put
00431  *
00432  *  Add a new element to the list before the current element but don't move the
00433  *  iterator to the new element.
00434  **********************************************************************/
00435 
00436 inline void CLIST_ITERATOR::add_before_stay_put(  // element to add
00437                                                 void *new_data) {
00438   CLIST_LINK *new_element;
00439 
00440   #ifndef NDEBUG
00441   if (!list)
00442     NO_LIST.error ("CLIST_ITERATOR::add_before_stay_put", ABORT, NULL);
00443   if (!new_data)
00444     BAD_PARAMETER.error ("CLIST_ITERATOR::add_before_stay_put", ABORT,
00445       "new_data is NULL");
00446   #endif
00447 
00448   new_element = new CLIST_LINK;
00449   new_element->data = new_data;
00450 
00451   if (list->empty ()) {
00452     new_element->next = new_element;
00453     list->last = new_element;
00454     prev = next = new_element;
00455     ex_current_was_last = TRUE;
00456     current = NULL;
00457   }
00458   else {
00459     prev->next = new_element;
00460     if (current) {               //not extracted
00461       new_element->next = current;
00462       if (next == current)
00463         next = new_element;
00464     }
00465     else {                       //current extracted
00466       new_element->next = next;
00467       if (ex_current_was_last)
00468         list->last = new_element;
00469     }
00470     prev = new_element;
00471   }
00472 }
00473 
00474 
00475 /***********************************************************************
00476  *                                                      CLIST_ITERATOR::add_list_after
00477  *
00478  *  Insert another list to this list after the current element but don't move the
00479  *  iterator.
00480  **********************************************************************/
00481 
00482 inline void CLIST_ITERATOR::add_list_after(CLIST *list_to_add) {
00483   #ifndef NDEBUG
00484   if (!list)
00485     NO_LIST.error ("CLIST_ITERATOR::add_list_after", ABORT, NULL);
00486   if (!list_to_add)
00487     BAD_PARAMETER.error ("CLIST_ITERATOR::add_list_after", ABORT,
00488       "list_to_add is NULL");
00489   #endif
00490 
00491   if (!list_to_add->empty ()) {
00492     if (list->empty ()) {
00493       list->last = list_to_add->last;
00494       prev = list->last;
00495       next = list->First ();
00496       ex_current_was_last = TRUE;
00497       current = NULL;
00498     }
00499     else {
00500       if (current) {             //not extracted
00501         current->next = list_to_add->First ();
00502         if (current == list->last)
00503           list->last = list_to_add->last;
00504         list_to_add->last->next = next;
00505         next = current->next;
00506       }
00507       else {                     //current extracted
00508         prev->next = list_to_add->First ();
00509         if (ex_current_was_last) {
00510           list->last = list_to_add->last;
00511           ex_current_was_last = FALSE;
00512         }
00513         list_to_add->last->next = next;
00514         next = prev->next;
00515       }
00516     }
00517     list_to_add->last = NULL;
00518   }
00519 }
00520 
00521 
00522 /***********************************************************************
00523  *                                                      CLIST_ITERATOR::add_list_before
00524  *
00525  *  Insert another list to this list before the current element. Move the
00526  *  iterator to the start of the inserted elements
00527  *  iterator.
00528  **********************************************************************/
00529 
00530 inline void CLIST_ITERATOR::add_list_before(CLIST *list_to_add) {
00531   #ifndef NDEBUG
00532   if (!list)
00533     NO_LIST.error ("CLIST_ITERATOR::add_list_before", ABORT, NULL);
00534   if (!list_to_add)
00535     BAD_PARAMETER.error ("CLIST_ITERATOR::add_list_before", ABORT,
00536       "list_to_add is NULL");
00537   #endif
00538 
00539   if (!list_to_add->empty ()) {
00540     if (list->empty ()) {
00541       list->last = list_to_add->last;
00542       prev = list->last;
00543       current = list->First ();
00544       next = current->next;
00545       ex_current_was_last = FALSE;
00546     }
00547     else {
00548       prev->next = list_to_add->First ();
00549       if (current) {             //not extracted
00550         list_to_add->last->next = current;
00551       }
00552       else {                     //current extracted
00553         list_to_add->last->next = next;
00554         if (ex_current_was_last)
00555           list->last = list_to_add->last;
00556         if (ex_current_was_cycle_pt)
00557           cycle_pt = prev->next;
00558       }
00559       current = prev->next;
00560       next = current->next;
00561     }
00562     list_to_add->last = NULL;
00563   }
00564 }
00565 
00566 
00567 /***********************************************************************
00568  *                                                      CLIST_ITERATOR::extract
00569  *
00570  *  Do extraction by removing current from the list, deleting the cons cell
00571  *  and returning the data to the caller, but NOT updating the iterator.  (So
00572  *  that any calling loop can do this.)  The iterator's current points to
00573  *  NULL.  If the data is to be deleted, this is the callers responsibility.
00574  **********************************************************************/
00575 
00576 inline void *CLIST_ITERATOR::extract() {
00577   void *extracted_data;
00578 
00579   #ifndef NDEBUG
00580   if (!list)
00581     NO_LIST.error ("CLIST_ITERATOR::extract", ABORT, NULL);
00582   if (!current)                  //list empty or
00583                                  //element extracted
00584     NULL_CURRENT.error ("CLIST_ITERATOR::extract",
00585       ABORT, NULL);
00586   #endif
00587 
00588   if (list->singleton()) {
00589     // Special case where we do need to change the iterator.
00590     prev = next = list->last = NULL;
00591   } else {
00592     prev->next = next;           //remove from list
00593 
00594     if (current == list->last) {
00595       list->last = prev;
00596       ex_current_was_last = TRUE;
00597     } else {
00598       ex_current_was_last = FALSE;
00599     }
00600   }
00601   // Always set ex_current_was_cycle_pt so an add/forward will work in a loop.
00602   ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
00603   extracted_data = current->data;
00604   delete(current);  //destroy CONS cell
00605   current = NULL;
00606   return extracted_data;
00607 }
00608 
00609 
00610 /***********************************************************************
00611  *                                                      CLIST_ITERATOR::move_to_first()
00612  *
00613  *  Move current so that it is set to the start of the list.
00614  *  Return data just in case anyone wants it.
00615  **********************************************************************/
00616 
00617 inline void *CLIST_ITERATOR::move_to_first() {
00618   #ifndef NDEBUG
00619   if (!list)
00620     NO_LIST.error ("CLIST_ITERATOR::move_to_first", ABORT, NULL);
00621   #endif
00622 
00623   current = list->First ();
00624   prev = list->last;
00625   next = current != NULL ? current->next : NULL;
00626   return current != NULL ? current->data : NULL;
00627 }
00628 
00629 
00630 /***********************************************************************
00631  *                                                      CLIST_ITERATOR::mark_cycle_pt()
00632  *
00633  *  Remember the current location so that we can tell whether we've returned
00634  *  to this point later.
00635  *
00636  *  If the current point is deleted either now, or in the future, the cycle
00637  *  point will be set to the next item which is set to current.  This could be
00638  *  by a forward, add_after_then_move or add_after_then_move.
00639  **********************************************************************/
00640 
00641 inline void CLIST_ITERATOR::mark_cycle_pt() {
00642   #ifndef NDEBUG
00643   if (!list)
00644     NO_LIST.error ("CLIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
00645   #endif
00646 
00647   if (current)
00648     cycle_pt = current;
00649   else
00650     ex_current_was_cycle_pt = TRUE;
00651   started_cycling = FALSE;
00652 }
00653 
00654 
00655 /***********************************************************************
00656  *                                                      CLIST_ITERATOR::at_first()
00657  *
00658  *  Are we at the start of the list?
00659  *
00660  **********************************************************************/
00661 
00662 inline BOOL8 CLIST_ITERATOR::at_first() {
00663   #ifndef NDEBUG
00664   if (!list)
00665     NO_LIST.error ("CLIST_ITERATOR::at_first", ABORT, NULL);
00666   #endif
00667 
00668                                  //we're at a deleted
00669   return ((list->empty ()) || (current == list->First ()) || ((current == NULL) &&
00670     (prev == list->last) &&      //NON-last pt between
00671     !ex_current_was_last));      //first and last
00672 }
00673 
00674 
00675 /***********************************************************************
00676  *                                                      CLIST_ITERATOR::at_last()
00677  *
00678  *  Are we at the end of the list?
00679  *
00680  **********************************************************************/
00681 
00682 inline BOOL8 CLIST_ITERATOR::at_last() {
00683   #ifndef NDEBUG
00684   if (!list)
00685     NO_LIST.error ("CLIST_ITERATOR::at_last", ABORT, NULL);
00686   #endif
00687 
00688                                  //we're at a deleted
00689   return ((list->empty ()) || (current == list->last) || ((current == NULL) &&
00690     (prev == list->last) &&      //last point between
00691     ex_current_was_last));       //first and last
00692 }
00693 
00694 
00695 /***********************************************************************
00696  *                                                      CLIST_ITERATOR::cycled_list()
00697  *
00698  *  Have we returned to the cycle_pt since it was set?
00699  *
00700  **********************************************************************/
00701 
00702 inline BOOL8 CLIST_ITERATOR::cycled_list() {
00703   #ifndef NDEBUG
00704   if (!list)
00705     NO_LIST.error ("CLIST_ITERATOR::cycled_list", ABORT, NULL);
00706   #endif
00707 
00708   return ((list->empty ()) || ((current == cycle_pt) && started_cycling));
00709 
00710 }
00711 
00712 
00713 /***********************************************************************
00714  *                                                      CLIST_ITERATOR::length()
00715  *
00716  *  Return the length of the list
00717  *
00718  **********************************************************************/
00719 
00720 inline inT32 CLIST_ITERATOR::length() {
00721   #ifndef NDEBUG
00722   if (!list)
00723     NO_LIST.error ("CLIST_ITERATOR::length", ABORT, NULL);
00724   #endif
00725 
00726   return list->length ();
00727 }
00728 
00729 
00730 /***********************************************************************
00731  *                                                      CLIST_ITERATOR::sort()
00732  *
00733  *  Sort the elements of the list, then reposition at the start.
00734  *
00735  **********************************************************************/
00736 
00737 inline void
00738 CLIST_ITERATOR::sort (           //sort elements
00739 int comparator (                 //comparison routine
00740 const void *, const void *)) {
00741   #ifndef NDEBUG
00742   if (!list)
00743     NO_LIST.error ("CLIST_ITERATOR::sort", ABORT, NULL);
00744   #endif
00745 
00746   list->sort (comparator);
00747   move_to_first();
00748 }
00749 
00750 
00751 /***********************************************************************
00752  *                                                      CLIST_ITERATOR::add_to_end
00753  *
00754  *  Add a new element to the end of the list without moving the iterator.
00755  *  This is provided because a single linked list cannot move to the last as
00756  *  the iterator couldn't set its prev pointer.  Adding to the end is
00757  *  essential for implementing
00758               queues.
00759 **********************************************************************/
00760 
00761 inline void CLIST_ITERATOR::add_to_end(  // element to add
00762                                        void *new_data) {
00763   CLIST_LINK *new_element;
00764 
00765   #ifndef NDEBUG
00766   if (!list)
00767     NO_LIST.error ("CLIST_ITERATOR::add_to_end", ABORT, NULL);
00768   if (!new_data)
00769     BAD_PARAMETER.error ("CLIST_ITERATOR::add_to_end", ABORT,
00770       "new_data is NULL");
00771   #endif
00772 
00773   if (this->at_last ()) {
00774     this->add_after_stay_put (new_data);
00775   }
00776   else {
00777     if (this->at_first ()) {
00778       this->add_before_stay_put (new_data);
00779       list->last = prev;
00780     }
00781     else {                       //Iteratr is elsewhere
00782       new_element = new CLIST_LINK;
00783       new_element->data = new_data;
00784 
00785       new_element->next = list->last->next;
00786       list->last->next = new_element;
00787       list->last = new_element;
00788     }
00789   }
00790 }
00791 
00792 
00793 /***********************************************************************
00794   QUOTE_IT   MACRO DEFINITION
00795   ===========================
00796 Replace <parm> with "<parm>".  <parm> may be an arbitrary number of tokens
00797 ***********************************************************************/
00798 
00799 #define QUOTE_IT( parm ) #parm
00800 
00801 /***********************************************************************
00802   CLISTIZE( CLASSNAME ) MACRO DEFINITION
00803   ======================================
00804 
00805 CLASSNAME is assumed to be the name of a class to be used in a CONS list
00806 
00807 NOTE:  Because we don't use virtual functions in the list code, the list code
00808 will NOT work correctly for classes derived from this.
00809 
00810 The macro generates:
00811   - An element deletion function:      CLASSNAME##_c1_zapper
00812   - An element copier function:
00813               CLASSNAME##_c1_copier
00814   - A CLIST subclass:           CLASSNAME##_CLIST
00815   - A CLIST_ITERATOR subclass:
00816               CLASSNAME##_C_IT
00817 
00818 NOTE: Generated names do NOT clash with those generated by ELISTIZE,
00819 ELIST2ISE and CLIST2IZE
00820 
00821 Two macros are provided: CLISTIZE and CLISTIZEH
00822 The ...IZEH macros just define the class names for use in .h files
00823 The ...IZE macros define the code use in .c files
00824 ***********************************************************************/
00825 
00826 /***********************************************************************
00827   CLISTIZEH( CLASSNAME )  MACRO
00828 
00829 CLISTIZEH is a concatenation of 3 fragments CLISTIZEH_A, CLISTIZEH_B and
00830 CLISTIZEH_C.
00831 ***********************************************************************/
00832 
00833 #define CLISTIZEH_A( CLASSNAME )                                                                                                \
00834                                                                                                                                                                 \
00835 extern DLLSYM void                      CLASSNAME##_c1_zapper(          /*delete a link*/               \
00836 void*                                           link);                                          /*link to delete*/              \
00837                                                                                                                                                                 \
00838 extern DLLSYM void*                     CLASSNAME##_c1_copier(          /*deep copy a link*/    \
00839 void*                                           old_element);   /*source link */
00840 
00841 #define CLISTIZEH_B( CLASSNAME )                                                                                                \
00842                                                                                                                                                                 \
00843 /***********************************************************************                \
00844 *                                                       CLASS - CLASSNAME##_CLIST                                                       \
00845 *                                                                                                                                                               \
00846 *                                                       List class for class CLASSNAME                                          \
00847 *                                                                                                                                                               \
00848 **********************************************************************/                 \
00849                                                                                                                                                                 \
00850 class DLLSYM                            CLASSNAME##_CLIST : public CLIST                                        \
00851 {                                                                                                                                                               \
00852 public:                                                                                                                                                 \
00853                                                         CLASSNAME##_CLIST():CLIST() {}                                          \
00854                                                                                                                 /* constructor */               \
00855                                                                                                                                                                 \
00856                                                         CLASSNAME##_CLIST(      /* don't construct */                   \
00857         const CLASSNAME##_CLIST&)                                                       /*by initial assign*/   \
00858         { DONT_CONSTRUCT_LIST_BY_COPY.error( QUOTE_IT( CLASSNAME##_CLIST ),                     \
00859                                                                                                                 ABORT, NULL ); }                \
00860                                                                                                                                                                 \
00861 void                                            deep_clear()                            /* delete elements */   \
00862         { CLIST::internal_deep_clear( &CLASSNAME##_c1_zapper ); }                                       \
00863                                                                                                                                                                 \
00864 void                                            operator=(                                      /* prevent assign */    \
00865         const CLASSNAME##_CLIST&)                                                                                                       \
00866         { DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_CLIST ),                                       \
00867                                                                                         ABORT, NULL ); }
00868 
00869 #define CLISTIZEH_C( CLASSNAME )                                                                                                \
00870                                                                                                                                                                 \
00871 };                                                                                                                                                              \
00872                                                                                                                                                                 \
00873                                                                                                                                                                 \
00874                                                                                                                                                                 \
00875 /***********************************************************************                \
00876 *                                                       CLASS - CLASSNAME##_C_IT                                                        \
00877 *                                                                                                                                                               \
00878 *                                                       Iterator class for class CLASSNAME##_CLIST                      \
00879 *                                                                                                                                                               \
00880 *  Note: We don't need to coerce pointers to member functions input                             \
00881 *  parameters as these are automatically converted to the type of the base              \
00882 *  type. ("A ptr to a class may be converted to a pointer to a public base              \
00883 *  class of that class")                                                                                                                \
00884 **********************************************************************/                 \
00885                                                                                                                                                                 \
00886 class DLLSYM                            CLASSNAME##_C_IT : public CLIST_ITERATOR                        \
00887 {                                                                                                                                                               \
00888 public:                                                                                                                                                 \
00889                                                         CLASSNAME##_C_IT():CLIST_ITERATOR(){}                           \
00890                                                                                                                                                                 \
00891                                                         CLASSNAME##_C_IT(                                                                       \
00892         CLASSNAME##_CLIST*              list):CLIST_ITERATOR(list){}                                            \
00893                                                                                                                                                                 \
00894         CLASSNAME*                      data()                                                                                          \
00895                 { return (CLASSNAME*) CLIST_ITERATOR::data(); }                                         \
00896                                                                                                                                                                 \
00897         CLASSNAME*                      data_relative(                                                                          \
00898         inT8                                    offset)                                                                                         \
00899                 { return (CLASSNAME*) CLIST_ITERATOR::data_relative( offset ); }                \
00900                                                                                                                                                                 \
00901         CLASSNAME*                      forward()                                                                                       \
00902                 { return (CLASSNAME*) CLIST_ITERATOR::forward(); }                                      \
00903                                                                                                                                                                 \
00904         CLASSNAME*                      extract()                                                                                       \
00905                 { return (CLASSNAME*) CLIST_ITERATOR::extract(); }                                      \
00906                                                                                                                                                                 \
00907         CLASSNAME*                      move_to_first()                                                                         \
00908                 { return (CLASSNAME*) CLIST_ITERATOR::move_to_first(); }                                \
00909                                                                                                                                                                 \
00910         CLASSNAME*                      move_to_last()                                                                          \
00911                 { return (CLASSNAME*) CLIST_ITERATOR::move_to_last(); }                         \
00912 };
00913 
00914 #define CLISTIZEH( CLASSNAME )                                          \
00915                                                                         \
00916 CLISTIZEH_A( CLASSNAME )                                                \
00917                                                                         \
00918 CLISTIZEH_B( CLASSNAME )                                                \
00919                                                                         \
00920 CLISTIZEH_C( CLASSNAME )
00921 
00922 /***********************************************************************
00923   CLISTIZE( CLASSNAME )  MACRO
00924 ***********************************************************************/
00925 
00926 #define CLISTIZE( CLASSNAME )                                                                                                   \
00927                                                                                                                                                                 \
00928 /***********************************************************************                \
00929 *                                                       CLASSNAME##_c1_zapper                                                           \
00930 *                                                                                                                                                               \
00931 *  A function which can delete a CLASSNAME element.  This is passed to the              \
00932 *  generic deep_clear list member function so that when a list is cleared the   \
00933 *  elements on the list are properly destroyed from the base class, even                \
00934 *  though we don't use a virtual destructor function.                                                   \
00935 **********************************************************************/                 \
00936                                                                                                                                                                 \
00937 DLLSYM void                                     CLASSNAME##_c1_zapper(          /*delete a link*/               \
00938 void*                                           link)                                           /*link to delete*/              \
00939 {                                                                                                                                                               \
00940 delete (CLASSNAME *) link;                                                                                                              \
00941 }                                                                                                                                                               \
00942 
00943 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines