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