tesseract  3.04.01
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
clst.h
Go to the documentation of this file.
1 /**********************************************************************
2  * File: clst.h (Formerly clist.h)
3  * Description: CONS cell list module include file.
4  * Author: Phil Cheatle
5  * Created: Mon Jan 28 08:33:13 GMT 1991
6  *
7  * (C) Copyright 1991, Hewlett-Packard Ltd.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  **********************************************************************/
19 
20 #ifndef CLST_H
21 #define CLST_H
22 
23 #include <stdio.h>
24 #include "host.h"
25 #include "serialis.h"
26 #include "lsterr.h"
27 
28 class CLIST_ITERATOR;
29 
30 /**********************************************************************
31  * CLASS - CLIST_LINK
32  *
33  * Generic link class for singly linked CONS cell lists
34  *
35  * Note: No destructor - elements are assumed to be destroyed EITHER after
36  * they have been extracted from a list OR by the CLIST destructor which
37  * walks the list.
38  **********************************************************************/
39 
41 {
42  friend class CLIST_ITERATOR;
43  friend class CLIST;
44 
45  CLIST_LINK *next;
46  void *data;
47 
48  public:
49  CLIST_LINK() { //constructor
50  data = next = NULL;
51  }
52 
53  CLIST_LINK( //copy constructor
54  const CLIST_LINK &) { //don't copy link
55  data = next = NULL;
56  }
57 
58  void operator= ( //don't copy links
59  const CLIST_LINK &) {
60  data = next = NULL;
61  }
62 };
63 
64 /**********************************************************************
65  * CLASS - CLIST
66  *
67  * Generic list class for singly linked CONS cell lists
68  **********************************************************************/
69 
71 {
72  friend class CLIST_ITERATOR;
73 
74  CLIST_LINK *last; //End of list
75  //(Points to head)
76  CLIST_LINK *First() { // return first
77  return last != NULL ? last->next : NULL;
78  }
79 
80  public:
81  CLIST() { //constructor
82  last = NULL;
83  }
84 
85  ~CLIST () { //destructor
86  shallow_clear();
87  }
88 
89  void internal_deep_clear ( //destroy all links
90  void (*zapper) (void *)); //ptr to zapper functn
91 
92  void shallow_clear(); //clear list but don't
93  //delete data elements
94 
95  bool empty() const { //is list empty?
96  return !last;
97  }
98 
99  bool singleton() const {
100  return last != NULL ? (last == last->next) : false;
101  }
102 
103  void shallow_copy( //dangerous!!
104  CLIST *from_list) { //beware destructors!!
105  last = from_list->last;
106  }
107 
108  void assign_to_sublist( //to this list
109  CLIST_ITERATOR *start_it, //from list start
110  CLIST_ITERATOR *end_it); //from list end
111 
112  inT32 length() const; //# elements in list
113 
114  void sort ( //sort elements
115  int comparator ( //comparison routine
116  const void *, const void *));
117 
118  // Assuming list has been sorted already, insert new_data to
119  // keep the list sorted according to the same comparison function.
120  // Comparison function is the same as used by sort, i.e. uses double
121  // indirection. Time is O(1) to add to beginning or end.
122  // Time is linear to add pre-sorted items to an empty list.
123  // If unique, then don't add duplicate entries.
124  // Returns true if the element was added to the list.
125  bool add_sorted(int comparator(const void*, const void*),
126  bool unique, void* new_data);
127 
128  // Assuming that the minuend and subtrahend are already sorted with
129  // the same comparison function, shallow clears this and then copies
130  // the set difference minuend - subtrahend to this, being the elements
131  // of minuend that do not compare equal to anything in subtrahend.
132  // If unique is true, any duplicates in minuend are also eliminated.
133  void set_subtract(int comparator(const void*, const void*), bool unique,
134  CLIST* minuend, CLIST* subtrahend);
135 
136 };
137 
138 /***********************************************************************
139  * CLASS - CLIST_ITERATOR
140  *
141  * Generic iterator class for singly linked lists with embedded links
142  **********************************************************************/
143 
145 {
147 
148  CLIST *list; //List being iterated
149  CLIST_LINK *prev; //prev element
150  CLIST_LINK *current; //current element
151  CLIST_LINK *next; //next element
152  BOOL8 ex_current_was_last; //current extracted
153  //was end of list
154  BOOL8 ex_current_was_cycle_pt; //current extracted
155  //was cycle point
156  CLIST_LINK *cycle_pt; //point we are cycling
157  //the list to.
158  BOOL8 started_cycling; //Have we moved off
159  //the start?
160 
161  CLIST_LINK *extract_sublist( //from this current...
162  CLIST_ITERATOR *other_it); //to other current
163 
164  public:
165  CLIST_ITERATOR() { //constructor
166  list = NULL;
167  } //unassigned list
168 
169  CLIST_ITERATOR( //constructor
170  CLIST *list_to_iterate);
171 
172  void set_to_list( //change list
173  CLIST *list_to_iterate);
174 
175  void add_after_then_move( //add after current &
176  void *new_data); //move to new
177 
178  void add_after_stay_put( //add after current &
179  void *new_data); //stay at current
180 
181  void add_before_then_move( //add before current &
182  void *new_data); //move to new
183 
184  void add_before_stay_put( //add before current &
185  void *new_data); //stay at current
186 
187  void add_list_after( //add a list &
188  CLIST *list_to_add); //stay at current
189 
190  void add_list_before( //add a list &
191  CLIST *list_to_add); //move to it 1st item
192 
193  void *data() { //get current data
194  #ifndef NDEBUG
195  if (!list)
196  NO_LIST.error ("CLIST_ITERATOR::data", ABORT, NULL);
197  if (!current)
198  NULL_DATA.error ("CLIST_ITERATOR::data", ABORT, NULL);
199  #endif
200  return current->data;
201  }
202 
203  void *data_relative( //get data + or - ...
204  inT8 offset); //offset from current
205 
206  void *forward(); //move to next element
207 
208  void *extract(); //remove from list
209 
210  void *move_to_first(); //go to start of list
211 
212  void *move_to_last(); //go to end of list
213 
214  void mark_cycle_pt(); //remember current
215 
216  BOOL8 empty() { //is list empty?
217  #ifndef NDEBUG
218  if (!list)
219  NO_LIST.error ("CLIST_ITERATOR::empty", ABORT, NULL);
220  #endif
221  return list->empty ();
222  }
223 
224  BOOL8 current_extracted() { //current extracted?
225  return !current;
226  }
227 
228  BOOL8 at_first(); //Current is first?
229 
230  BOOL8 at_last(); //Current is last?
231 
232  BOOL8 cycled_list(); //Completed a cycle?
233 
234  void add_to_end( //add at end &
235  void *new_data); //don't move
236 
237  void exchange( //positions of 2 links
238  CLIST_ITERATOR *other_it); //other iterator
239 
240  inT32 length(); //# elements in list
241 
242  void sort ( //sort elements
243  int comparator ( //comparison routine
244  const void *, const void *));
245 
246 };
247 
248 /***********************************************************************
249  * CLIST_ITERATOR::set_to_list
250  *
251  * (Re-)initialise the iterator to point to the start of the list_to_iterate
252  * over.
253  **********************************************************************/
254 
255 inline void CLIST_ITERATOR::set_to_list( //change list
256  CLIST *list_to_iterate) {
257  #ifndef NDEBUG
258  if (!list_to_iterate)
259  BAD_PARAMETER.error ("CLIST_ITERATOR::set_to_list", ABORT,
260  "list_to_iterate is NULL");
261  #endif
262 
263  list = list_to_iterate;
264  prev = list->last;
265  current = list->First ();
266  next = current != NULL ? current->next : NULL;
267  cycle_pt = NULL; //await explicit set
268  started_cycling = FALSE;
269  ex_current_was_last = FALSE;
270  ex_current_was_cycle_pt = FALSE;
271 }
272 
273 
274 /***********************************************************************
275  * CLIST_ITERATOR::CLIST_ITERATOR
276  *
277  * CONSTRUCTOR - set iterator to specified list;
278  **********************************************************************/
279 
280 inline CLIST_ITERATOR::CLIST_ITERATOR(CLIST *list_to_iterate) {
281  set_to_list(list_to_iterate);
282 }
283 
284 
285 /***********************************************************************
286  * CLIST_ITERATOR::add_after_then_move
287  *
288  * Add a new element to the list after the current element and move the
289  * iterator to the new element.
290  **********************************************************************/
291 
292 inline void CLIST_ITERATOR::add_after_then_move( // element to add
293  void *new_data) {
294  CLIST_LINK *new_element;
295 
296  #ifndef NDEBUG
297  if (!list)
298  NO_LIST.error ("CLIST_ITERATOR::add_after_then_move", ABORT, NULL);
299  if (!new_data)
300  BAD_PARAMETER.error ("CLIST_ITERATOR::add_after_then_move", ABORT,
301  "new_data is NULL");
302  #endif
303 
304  new_element = new CLIST_LINK;
305  new_element->data = new_data;
306 
307  if (list->empty ()) {
308  new_element->next = new_element;
309  list->last = new_element;
310  prev = next = new_element;
311  }
312  else {
313  new_element->next = next;
314 
315  if (current) { //not extracted
316  current->next = new_element;
317  prev = current;
318  if (current == list->last)
319  list->last = new_element;
320  }
321  else { //current extracted
322  prev->next = new_element;
323  if (ex_current_was_last)
324  list->last = new_element;
325  if (ex_current_was_cycle_pt)
326  cycle_pt = new_element;
327  }
328  }
329  current = new_element;
330 }
331 
332 
333 /***********************************************************************
334  * CLIST_ITERATOR::add_after_stay_put
335  *
336  * Add a new element to the list after the current element but do not move
337  * the iterator to the new element.
338  **********************************************************************/
339 
340 inline void CLIST_ITERATOR::add_after_stay_put( // element to add
341  void *new_data) {
342  CLIST_LINK *new_element;
343 
344  #ifndef NDEBUG
345  if (!list)
346  NO_LIST.error ("CLIST_ITERATOR::add_after_stay_put", ABORT, NULL);
347  if (!new_data)
348  BAD_PARAMETER.error ("CLIST_ITERATOR::add_after_stay_put", ABORT,
349  "new_data is NULL");
350  #endif
351 
352  new_element = new CLIST_LINK;
353  new_element->data = new_data;
354 
355  if (list->empty ()) {
356  new_element->next = new_element;
357  list->last = new_element;
358  prev = next = new_element;
359  ex_current_was_last = FALSE;
360  current = NULL;
361  }
362  else {
363  new_element->next = next;
364 
365  if (current) { //not extracted
366  current->next = new_element;
367  if (prev == current)
368  prev = new_element;
369  if (current == list->last)
370  list->last = new_element;
371  }
372  else { //current extracted
373  prev->next = new_element;
374  if (ex_current_was_last) {
375  list->last = new_element;
376  ex_current_was_last = FALSE;
377  }
378  }
379  next = new_element;
380  }
381 }
382 
383 
384 /***********************************************************************
385  * CLIST_ITERATOR::add_before_then_move
386  *
387  * Add a new element to the list before the current element and move the
388  * iterator to the new element.
389  **********************************************************************/
390 
391 inline void CLIST_ITERATOR::add_before_then_move( // element to add
392  void *new_data) {
393  CLIST_LINK *new_element;
394 
395  #ifndef NDEBUG
396  if (!list)
397  NO_LIST.error ("CLIST_ITERATOR::add_before_then_move", ABORT, NULL);
398  if (!new_data)
399  BAD_PARAMETER.error ("CLIST_ITERATOR::add_before_then_move", ABORT,
400  "new_data is NULL");
401  #endif
402 
403  new_element = new CLIST_LINK;
404  new_element->data = new_data;
405 
406  if (list->empty ()) {
407  new_element->next = new_element;
408  list->last = new_element;
409  prev = next = new_element;
410  }
411  else {
412  prev->next = new_element;
413  if (current) { //not extracted
414  new_element->next = current;
415  next = current;
416  }
417  else { //current extracted
418  new_element->next = next;
419  if (ex_current_was_last)
420  list->last = new_element;
421  if (ex_current_was_cycle_pt)
422  cycle_pt = new_element;
423  }
424  }
425  current = new_element;
426 }
427 
428 
429 /***********************************************************************
430  * CLIST_ITERATOR::add_before_stay_put
431  *
432  * Add a new element to the list before the current element but don't move the
433  * iterator to the new element.
434  **********************************************************************/
435 
436 inline void CLIST_ITERATOR::add_before_stay_put( // element to add
437  void *new_data) {
438  CLIST_LINK *new_element;
439 
440  #ifndef NDEBUG
441  if (!list)
442  NO_LIST.error ("CLIST_ITERATOR::add_before_stay_put", ABORT, NULL);
443  if (!new_data)
444  BAD_PARAMETER.error ("CLIST_ITERATOR::add_before_stay_put", ABORT,
445  "new_data is NULL");
446  #endif
447 
448  new_element = new CLIST_LINK;
449  new_element->data = new_data;
450 
451  if (list->empty ()) {
452  new_element->next = new_element;
453  list->last = new_element;
454  prev = next = new_element;
455  ex_current_was_last = TRUE;
456  current = NULL;
457  }
458  else {
459  prev->next = new_element;
460  if (current) { //not extracted
461  new_element->next = current;
462  if (next == current)
463  next = new_element;
464  }
465  else { //current extracted
466  new_element->next = next;
467  if (ex_current_was_last)
468  list->last = new_element;
469  }
470  prev = new_element;
471  }
472 }
473 
474 
475 /***********************************************************************
476  * CLIST_ITERATOR::add_list_after
477  *
478  * Insert another list to this list after the current element but don't move the
479  * iterator.
480  **********************************************************************/
481 
482 inline void CLIST_ITERATOR::add_list_after(CLIST *list_to_add) {
483  #ifndef NDEBUG
484  if (!list)
485  NO_LIST.error ("CLIST_ITERATOR::add_list_after", ABORT, NULL);
486  if (!list_to_add)
487  BAD_PARAMETER.error ("CLIST_ITERATOR::add_list_after", ABORT,
488  "list_to_add is NULL");
489  #endif
490 
491  if (!list_to_add->empty ()) {
492  if (list->empty ()) {
493  list->last = list_to_add->last;
494  prev = list->last;
495  next = list->First ();
496  ex_current_was_last = TRUE;
497  current = NULL;
498  }
499  else {
500  if (current) { //not extracted
501  current->next = list_to_add->First ();
502  if (current == list->last)
503  list->last = list_to_add->last;
504  list_to_add->last->next = next;
505  next = current->next;
506  }
507  else { //current extracted
508  prev->next = list_to_add->First ();
509  if (ex_current_was_last) {
510  list->last = list_to_add->last;
511  ex_current_was_last = FALSE;
512  }
513  list_to_add->last->next = next;
514  next = prev->next;
515  }
516  }
517  list_to_add->last = NULL;
518  }
519 }
520 
521 
522 /***********************************************************************
523  * CLIST_ITERATOR::add_list_before
524  *
525  * Insert another list to this list before the current element. Move the
526  * iterator to the start of the inserted elements
527  * iterator.
528  **********************************************************************/
529 
530 inline void CLIST_ITERATOR::add_list_before(CLIST *list_to_add) {
531  #ifndef NDEBUG
532  if (!list)
533  NO_LIST.error ("CLIST_ITERATOR::add_list_before", ABORT, NULL);
534  if (!list_to_add)
535  BAD_PARAMETER.error ("CLIST_ITERATOR::add_list_before", ABORT,
536  "list_to_add is NULL");
537  #endif
538 
539  if (!list_to_add->empty ()) {
540  if (list->empty ()) {
541  list->last = list_to_add->last;
542  prev = list->last;
543  current = list->First ();
544  next = current->next;
545  ex_current_was_last = FALSE;
546  }
547  else {
548  prev->next = list_to_add->First ();
549  if (current) { //not extracted
550  list_to_add->last->next = current;
551  }
552  else { //current extracted
553  list_to_add->last->next = next;
554  if (ex_current_was_last)
555  list->last = list_to_add->last;
556  if (ex_current_was_cycle_pt)
557  cycle_pt = prev->next;
558  }
559  current = prev->next;
560  next = current->next;
561  }
562  list_to_add->last = NULL;
563  }
564 }
565 
566 
567 /***********************************************************************
568  * CLIST_ITERATOR::extract
569  *
570  * Do extraction by removing current from the list, deleting the cons cell
571  * and returning the data to the caller, but NOT updating the iterator. (So
572  * that any calling loop can do this.) The iterator's current points to
573  * NULL. If the data is to be deleted, this is the callers responsibility.
574  **********************************************************************/
575 
576 inline void *CLIST_ITERATOR::extract() {
577  void *extracted_data;
578 
579  #ifndef NDEBUG
580  if (!list)
581  NO_LIST.error ("CLIST_ITERATOR::extract", ABORT, NULL);
582  if (!current) //list empty or
583  //element extracted
584  NULL_CURRENT.error ("CLIST_ITERATOR::extract",
585  ABORT, NULL);
586  #endif
587 
588  if (list->singleton()) {
589  // Special case where we do need to change the iterator.
590  prev = next = list->last = NULL;
591  } else {
592  prev->next = next; //remove from list
593 
594  if (current == list->last) {
595  list->last = prev;
596  ex_current_was_last = TRUE;
597  } else {
598  ex_current_was_last = FALSE;
599  }
600  }
601  // Always set ex_current_was_cycle_pt so an add/forward will work in a loop.
602  ex_current_was_cycle_pt = (current == cycle_pt) ? TRUE : FALSE;
603  extracted_data = current->data;
604  delete(current); //destroy CONS cell
605  current = NULL;
606  return extracted_data;
607 }
608 
609 
610 /***********************************************************************
611  * CLIST_ITERATOR::move_to_first()
612  *
613  * Move current so that it is set to the start of the list.
614  * Return data just in case anyone wants it.
615  **********************************************************************/
616 
618  #ifndef NDEBUG
619  if (!list)
620  NO_LIST.error ("CLIST_ITERATOR::move_to_first", ABORT, NULL);
621  #endif
622 
623  current = list->First ();
624  prev = list->last;
625  next = current != NULL ? current->next : NULL;
626  return current != NULL ? current->data : NULL;
627 }
628 
629 
630 /***********************************************************************
631  * CLIST_ITERATOR::mark_cycle_pt()
632  *
633  * Remember the current location so that we can tell whether we've returned
634  * to this point later.
635  *
636  * If the current point is deleted either now, or in the future, the cycle
637  * point will be set to the next item which is set to current. This could be
638  * by a forward, add_after_then_move or add_after_then_move.
639  **********************************************************************/
640 
642  #ifndef NDEBUG
643  if (!list)
644  NO_LIST.error ("CLIST_ITERATOR::mark_cycle_pt", ABORT, NULL);
645  #endif
646 
647  if (current)
648  cycle_pt = current;
649  else
650  ex_current_was_cycle_pt = TRUE;
651  started_cycling = FALSE;
652 }
653 
654 
655 /***********************************************************************
656  * CLIST_ITERATOR::at_first()
657  *
658  * Are we at the start of the list?
659  *
660  **********************************************************************/
661 
663  #ifndef NDEBUG
664  if (!list)
665  NO_LIST.error ("CLIST_ITERATOR::at_first", ABORT, NULL);
666  #endif
667 
668  //we're at a deleted
669  return ((list->empty ()) || (current == list->First ()) || ((current == NULL) &&
670  (prev == list->last) && //NON-last pt between
671  !ex_current_was_last)); //first and last
672 }
673 
674 
675 /***********************************************************************
676  * CLIST_ITERATOR::at_last()
677  *
678  * Are we at the end of the list?
679  *
680  **********************************************************************/
681 
683  #ifndef NDEBUG
684  if (!list)
685  NO_LIST.error ("CLIST_ITERATOR::at_last", ABORT, NULL);
686  #endif
687 
688  //we're at a deleted
689  return ((list->empty ()) || (current == list->last) || ((current == NULL) &&
690  (prev == list->last) && //last point between
691  ex_current_was_last)); //first and last
692 }
693 
694 
695 /***********************************************************************
696  * CLIST_ITERATOR::cycled_list()
697  *
698  * Have we returned to the cycle_pt since it was set?
699  *
700  **********************************************************************/
701 
703  #ifndef NDEBUG
704  if (!list)
705  NO_LIST.error ("CLIST_ITERATOR::cycled_list", ABORT, NULL);
706  #endif
707 
708  return ((list->empty ()) || ((current == cycle_pt) && started_cycling));
709 
710 }
711 
712 
713 /***********************************************************************
714  * CLIST_ITERATOR::length()
715  *
716  * Return the length of the list
717  *
718  **********************************************************************/
719 
721  #ifndef NDEBUG
722  if (!list)
723  NO_LIST.error ("CLIST_ITERATOR::length", ABORT, NULL);
724  #endif
725 
726  return list->length ();
727 }
728 
729 
730 /***********************************************************************
731  * CLIST_ITERATOR::sort()
732  *
733  * Sort the elements of the list, then reposition at the start.
734  *
735  **********************************************************************/
736 
737 inline void
738 CLIST_ITERATOR::sort ( //sort elements
739 int comparator ( //comparison routine
740 const void *, const void *)) {
741  #ifndef NDEBUG
742  if (!list)
743  NO_LIST.error ("CLIST_ITERATOR::sort", ABORT, NULL);
744  #endif
745 
746  list->sort (comparator);
747  move_to_first();
748 }
749 
750 
751 /***********************************************************************
752  * CLIST_ITERATOR::add_to_end
753  *
754  * Add a new element to the end of the list without moving the iterator.
755  * This is provided because a single linked list cannot move to the last as
756  * the iterator couldn't set its prev pointer. Adding to the end is
757  * essential for implementing
758  queues.
759 **********************************************************************/
760 
761 inline void CLIST_ITERATOR::add_to_end( // element to add
762  void *new_data) {
763  CLIST_LINK *new_element;
764 
765  #ifndef NDEBUG
766  if (!list)
767  NO_LIST.error ("CLIST_ITERATOR::add_to_end", ABORT, NULL);
768  if (!new_data)
769  BAD_PARAMETER.error ("CLIST_ITERATOR::add_to_end", ABORT,
770  "new_data is NULL");
771  #endif
772 
773  if (this->at_last ()) {
774  this->add_after_stay_put (new_data);
775  }
776  else {
777  if (this->at_first ()) {
778  this->add_before_stay_put (new_data);
779  list->last = prev;
780  }
781  else { //Iteratr is elsewhere
782  new_element = new CLIST_LINK;
783  new_element->data = new_data;
784 
785  new_element->next = list->last->next;
786  list->last->next = new_element;
787  list->last = new_element;
788  }
789  }
790 }
791 
792 
793 /***********************************************************************
794  QUOTE_IT MACRO DEFINITION
795  ===========================
796 Replace <parm> with "<parm>". <parm> may be an arbitrary number of tokens
797 ***********************************************************************/
798 
799 #define QUOTE_IT( parm ) #parm
800 
801 /***********************************************************************
802  CLISTIZE( CLASSNAME ) MACRO DEFINITION
803  ======================================
804 
805 CLASSNAME is assumed to be the name of a class to be used in a CONS list
806 
807 NOTE: Because we don't use virtual functions in the list code, the list code
808 will NOT work correctly for classes derived from this.
809 
810 The macro generates:
811  - An element deletion function: CLASSNAME##_c1_zapper
812  - An element copier function:
813  CLASSNAME##_c1_copier
814  - A CLIST subclass: CLASSNAME##_CLIST
815  - A CLIST_ITERATOR subclass:
816  CLASSNAME##_C_IT
817 
818 NOTE: Generated names do NOT clash with those generated by ELISTIZE,
819 ELIST2ISE and CLIST2IZE
820 
821 Two macros are provided: CLISTIZE and CLISTIZEH
822 The ...IZEH macros just define the class names for use in .h files
823 The ...IZE macros define the code use in .c files
824 ***********************************************************************/
825 
826 /***********************************************************************
827  CLISTIZEH( CLASSNAME ) MACRO
828 
829 CLISTIZEH is a concatenation of 3 fragments CLISTIZEH_A, CLISTIZEH_B and
830 CLISTIZEH_C.
831 ***********************************************************************/
832 
833 #define CLISTIZEH_A( CLASSNAME ) \
834  \
835 extern DLLSYM void CLASSNAME##_c1_zapper( /*delete a link*/ \
836 void* link); /*link to delete*/ \
837  \
838 extern DLLSYM void* CLASSNAME##_c1_copier( /*deep copy a link*/ \
839 void* old_element); /*source link */
840 
841 #define CLISTIZEH_B( CLASSNAME ) \
842  \
843 /*********************************************************************** \
844 * CLASS - CLASSNAME##_CLIST \
845 * \
846 * List class for class CLASSNAME \
847 * \
848 **********************************************************************/ \
849  \
850 class DLLSYM CLASSNAME##_CLIST : public CLIST \
851 { \
852 public: \
853  CLASSNAME##_CLIST():CLIST() {} \
854  /* constructor */ \
855  \
856  CLASSNAME##_CLIST( /* don't construct */ \
857  const CLASSNAME##_CLIST&) /*by initial assign*/ \
858  { DONT_CONSTRUCT_LIST_BY_COPY.error( QUOTE_IT( CLASSNAME##_CLIST ), \
859  ABORT, NULL ); } \
860  \
861 void deep_clear() /* delete elements */ \
862  { CLIST::internal_deep_clear( &CLASSNAME##_c1_zapper ); } \
863  \
864 void operator=( /* prevent assign */ \
865  const CLASSNAME##_CLIST&) \
866  { DONT_ASSIGN_LISTS.error( QUOTE_IT( CLASSNAME##_CLIST ), \
867  ABORT, NULL ); }
868 
869 #define CLISTIZEH_C( CLASSNAME ) \
870  \
871 }; \
872  \
873  \
874  \
875 /*********************************************************************** \
876 * CLASS - CLASSNAME##_C_IT \
877 * \
878 * Iterator class for class CLASSNAME##_CLIST \
879 * \
880 * Note: We don't need to coerce pointers to member functions input \
881 * parameters as these are automatically converted to the type of the base \
882 * type. ("A ptr to a class may be converted to a pointer to a public base \
883 * class of that class") \
884 **********************************************************************/ \
885  \
886 class DLLSYM CLASSNAME##_C_IT : public CLIST_ITERATOR \
887 { \
888 public: \
889  CLASSNAME##_C_IT():CLIST_ITERATOR(){} \
890  \
891  CLASSNAME##_C_IT( \
892  CLASSNAME##_CLIST* list):CLIST_ITERATOR(list){} \
893  \
894  CLASSNAME* data() \
895  { return (CLASSNAME*) CLIST_ITERATOR::data(); } \
896  \
897  CLASSNAME* data_relative( \
898  inT8 offset) \
899  { return (CLASSNAME*) CLIST_ITERATOR::data_relative( offset ); } \
900  \
901  CLASSNAME* forward() \
902  { return (CLASSNAME*) CLIST_ITERATOR::forward(); } \
903  \
904  CLASSNAME* extract() \
905  { return (CLASSNAME*) CLIST_ITERATOR::extract(); } \
906  \
907  CLASSNAME* move_to_first() \
908  { return (CLASSNAME*) CLIST_ITERATOR::move_to_first(); } \
909  \
910  CLASSNAME* move_to_last() \
911  { return (CLASSNAME*) CLIST_ITERATOR::move_to_last(); } \
912 };
913 
914 #define CLISTIZEH( CLASSNAME ) \
915  \
916 CLISTIZEH_A( CLASSNAME ) \
917  \
918 CLISTIZEH_B( CLASSNAME ) \
919  \
920 CLISTIZEH_C( CLASSNAME )
921 
922 /***********************************************************************
923  CLISTIZE( CLASSNAME ) MACRO
924 ***********************************************************************/
925 
926 #define CLISTIZE( CLASSNAME ) \
927  \
928 /*********************************************************************** \
929 * CLASSNAME##_c1_zapper \
930 * \
931 * A function which can delete a CLASSNAME element. This is passed to the \
932 * generic deep_clear list member function so that when a list is cleared the \
933 * elements on the list are properly destroyed from the base class, even \
934 * though we don't use a virtual destructor function. \
935 **********************************************************************/ \
936  \
937 DLLSYM void CLASSNAME##_c1_zapper( /*delete a link*/ \
938 void* link) /*link to delete*/ \
939 { \
940 delete (CLASSNAME *) link; \
941 } \
942 
943 #endif
int inT32
Definition: host.h:102
void * extract()
Definition: clst.h:576
void * move_to_first()
Definition: clst.h:617
BOOL8 empty()
Definition: clst.h:216
void mark_cycle_pt()
Definition: clst.h:641
SIGNED char inT8
Definition: host.h:98
BOOL8 cycled_list()
Definition: clst.h:702
void set_to_list(CLIST *list_to_iterate)
Definition: clst.h:255
Definition: clst.h:70
void assign_to_sublist(CLIST_ITERATOR *start_it, CLIST_ITERATOR *end_it)
Definition: clst.cpp:98
void add_before_stay_put(void *new_data)
Definition: clst.h:436
void add_list_after(CLIST *list_to_add)
Definition: clst.h:482
#define FALSE
Definition: capi.h:29
CLIST_ITERATOR()
Definition: clst.h:165
bool singleton() const
Definition: clst.h:99
inT32 length()
Definition: clst.h:720
void add_after_stay_put(void *new_data)
Definition: clst.h:340
const ERRCODE BAD_PARAMETER
Definition: lsterr.h:39
const ERRCODE NO_LIST
Definition: lsterr.h:32
~CLIST()
Definition: clst.h:85
BOOL8 at_last()
Definition: clst.h:682
CLIST_LINK()
Definition: clst.h:49
void add_after_then_move(void *new_data)
Definition: clst.h:292
void sort(int comparator(const void *, const void *))
Definition: clst.h:738
void shallow_copy(CLIST *from_list)
Definition: clst.h:103
inT32 length() const
Definition: clst.cpp:117
void error(const char *caller, TessErrorLogCode action, const char *format,...) const
Definition: errcode.cpp:40
struct list_rec * next
Definition: oldlist.h:130
CLIST_LINK(const CLIST_LINK &)
Definition: clst.h:53
void add_list_before(CLIST *list_to_add)
Definition: clst.h:530
bool empty() const
Definition: clst.h:95
const ERRCODE NULL_DATA
Definition: lsterr.h:34
BOOL8 at_first()
Definition: clst.h:662
CLIST()
Definition: clst.h:81
BOOL8 current_extracted()
Definition: clst.h:224
Definition: errcode.h:30
unsigned char BOOL8
Definition: host.h:113
#define TRUE
Definition: capi.h:28
void sort(int comparator(const void *, const void *))
Definition: clst.cpp:134
void add_before_then_move(void *new_data)
Definition: clst.h:391
#define DLLSYM
Definition: platform.h:25
void add_to_end(void *new_data)
Definition: clst.h:761
const ERRCODE NULL_CURRENT
Definition: lsterr.h:35
LIST last(LIST var_list)
Definition: oldlist.cpp:277
void * data()
Definition: clst.h:193