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