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