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