tesseract v5.3.3.20231005
elst2.h
Go to the documentation of this file.
1/**********************************************************************
2 * File: elst2.h (Formerly elist2.h)
3 * Description: Double linked embedded 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 ELST2_H
20#define ELST2_H
21
22#include "list.h"
23#include "lsterr.h"
24#include "serialis.h"
25
26#include <cstdio>
27
28namespace tesseract {
29
30class ELIST2_ITERATOR;
31
32/**********************************************************************
33DESIGN NOTE
34===========
35
36It would probably be possible to implement the ELIST2 classes as derived
37classes from ELIST. I haven't done this because:
38
39a) I think it would be harder to understand the code
40(Though the problem with not inheriting is that changes to ELIST must be
41 reflected in ELIST2 and vice versa)
42
43b) Most of the code is inline so:
44i) The duplication in source does not affect the run time code size - the
45 code is copied inline anyway!
46
47 ii) The compiler should have a bit less work to do!
48**********************************************************************/
49
50/**********************************************************************
51 * CLASS - ELIST2_LINK
52 *
53 * Generic link class for doubly linked lists with embedded links
54 *
55 * Note: No destructor - elements are assumed to be destroyed EITHER after
56 * they have been extracted from a list OR by the ELIST2 destructor which
57 * walks the list.
58 **********************************************************************/
59
61 friend class ELIST2_ITERATOR;
62 friend class ELIST2;
63
64 ELIST2_LINK *prev;
66
67public:
68 ELIST2_LINK() { // constructor
69 prev = next = nullptr;
70 }
71
72 ELIST2_LINK(const ELIST2_LINK &) = delete;
73
74 // The assignment operator is required for WERD.
75 void operator=(const ELIST2_LINK &) {
76 prev = next = nullptr;
77 }
78};
79
80/**********************************************************************
81 * CLASS - ELIST2
82 *
83 * Generic list class for doubly linked lists with embedded links
84 **********************************************************************/
85
87 friend class ELIST2_ITERATOR;
88
89 ELIST2_LINK *last = nullptr; // End of list
90 //(Points to head)
91 ELIST2_LINK *First() { // return first
92 return last ? last->next : nullptr;
93 }
94
95public:
96 // destroy all links
97 void internal_clear(void (*zapper)(void *));
98
99 bool empty() const { // is list empty?
100 return !last;
101 }
102
103 bool singleton() const {
104 return last ? (last == last->next) : false;
105 }
106
107 void shallow_copy( // dangerous!!
108 ELIST2 *from_list) { // beware destructors!!
109 last = from_list->last;
110 }
111
112 // ptr to copier functn
114 const ELIST2 *list); // list being copied
115
116 void assign_to_sublist( // to this list
117 ELIST2_ITERATOR *start_it, // from list start
118 ELIST2_ITERATOR *end_it); // from list end
119
120 // # elements in list
121 int32_t length() const {
122 int32_t count = 0;
123 if (last != nullptr) {
124 count = 1;
125 for (auto it = last->next; it != last; it = it->next) {
126 count++;
127 }
128 }
129 return count;
130 }
131
132 void sort( // sort elements
133 int comparator( // comparison routine
134 const void *, const void *));
135
136 // Assuming list has been sorted already, insert new_link to
137 // keep the list sorted according to the same comparison function.
138 // Comparison function is the same as used by sort, i.e. uses double
139 // indirection. Time is O(1) to add to beginning or end.
140 // Time is linear to add pre-sorted items to an empty list.
141 void add_sorted(int comparator(const void *, const void *), ELIST2_LINK *new_link);
142};
143
144/***********************************************************************
145 * CLASS - ELIST2_ITERATOR
146 *
147 * Generic iterator class for doubly linked lists with embedded
148 *links
149 **********************************************************************/
150
153
154 ELIST2 *list; // List being iterated
155 ELIST2_LINK *prev; // prev element
156 ELIST2_LINK *current; // current element
157 ELIST2_LINK *next; // next element
158 ELIST2_LINK *cycle_pt; // point we are cycling the list to.
159 bool ex_current_was_last; // current extracted was end of list
160 bool ex_current_was_cycle_pt; // current extracted was cycle point
161 bool started_cycling; // Have we moved off the start?
162
163 ELIST2_LINK *extract_sublist( // from this current...
164 ELIST2_ITERATOR *other_it); // to other current
165
166public:
167 ELIST2_ITERATOR( // constructor
168 ELIST2 *list_to_iterate);
169
170 void set_to_list( // change list
171 ELIST2 *list_to_iterate);
172
173 void add_after_then_move( // add after current &
174 ELIST2_LINK *new_link); // move to new
175
176 void add_after_stay_put( // add after current &
177 ELIST2_LINK *new_link); // stay at current
178
179 void add_before_then_move( // add before current &
180 ELIST2_LINK *new_link); // move to new
181
182 void add_before_stay_put( // add before current &
183 ELIST2_LINK *new_link); // stay at current
184
185 void add_list_after( // add a list &
186 ELIST2 *list_to_add); // stay at current
187
188 void add_list_before( // add a list &
189 ELIST2 *list_to_add); // move to it 1st item
190
191 ELIST2_LINK *data() { // get current data
192#ifndef NDEBUG
193 if (!current) {
194 NULL_DATA.error("ELIST2_ITERATOR::data", ABORT);
195 }
196 if (!list) {
197 NO_LIST.error("ELIST2_ITERATOR::data", ABORT);
198 }
199#endif
200 return current;
201 }
202
203 ELIST2_LINK *data_relative( // get data + or - ...
204 int8_t offset); // offset from current
205
206 ELIST2_LINK *forward(); // move to next element
207
208 ELIST2_LINK *backward(); // move to prev element
209
210 ELIST2_LINK *extract(); // remove from list
211
212 // go to start of list
213 ELIST2_LINK *move_to_first();
214
215 ELIST2_LINK *move_to_last(); // go to end of list
216
217 void mark_cycle_pt(); // remember current
218
219 bool empty() const { // is list empty?
220#ifndef NDEBUG
221 if (!list) {
222 NO_LIST.error("ELIST2_ITERATOR::empty", ABORT);
223 }
224#endif
225 return list->empty();
226 }
227
228 bool current_extracted() const { // current extracted?
229 return !current;
230 }
231
232 bool at_first() const; // Current is first?
233
234 bool at_last() const; // Current is last?
235
236 bool cycled_list() const; // Completed a cycle?
237
238 void add_to_end( // add at end &
239 ELIST2_LINK *new_link); // don't move
240
241 void exchange( // positions of 2 links
242 ELIST2_ITERATOR *other_it); // other iterator
243
244 //# elements in list
245 int32_t length() const {
246 return list->length();
247 }
248
249 void sort( // sort elements
250 int comparator( // comparison routine
251 const void *, const void *));
252
253private:
254 // Don't use the following constructor.
255 ELIST2_ITERATOR() = delete;
256};
257
258/***********************************************************************
259 * ELIST2_ITERATOR::set_to_list
260 *
261 * (Re-)initialise the iterator to point to the start of the list_to_iterate
262 * over.
263 **********************************************************************/
264
265inline void ELIST2_ITERATOR::set_to_list( // change list
266 ELIST2 *list_to_iterate) {
267#ifndef NDEBUG
268 if (!list_to_iterate) {
269 BAD_PARAMETER.error("ELIST2_ITERATOR::set_to_list", ABORT, "list_to_iterate is nullptr");
270 }
271#endif
272
273 list = list_to_iterate;
274 prev = list->last;
275 current = list->First();
276 next = current ? current->next : nullptr;
277 cycle_pt = nullptr; // await explicit set
278 started_cycling = false;
279 ex_current_was_last = false;
280 ex_current_was_cycle_pt = false;
281}
282
283/***********************************************************************
284 * ELIST2_ITERATOR::ELIST2_ITERATOR
285 *
286 * CONSTRUCTOR - set iterator to specified list;
287 **********************************************************************/
288
289inline ELIST2_ITERATOR::ELIST2_ITERATOR(ELIST2 *list_to_iterate) {
290 set_to_list(list_to_iterate);
291}
292
293/***********************************************************************
294 * ELIST2_ITERATOR::add_after_then_move
295 *
296 * Add a new element to the list after the current element and move the
297 * iterator to the new element.
298 **********************************************************************/
299
300inline void ELIST2_ITERATOR::add_after_then_move( // element to add
301 ELIST2_LINK *new_element) {
302#ifndef NDEBUG
303 if (!list) {
304 NO_LIST.error("ELIST2_ITERATOR::add_after_then_move", ABORT);
305 }
306 if (!new_element) {
307 BAD_PARAMETER.error("ELIST2_ITERATOR::add_after_then_move", ABORT, "new_element is nullptr");
308 }
309 if (new_element->next) {
310 STILL_LINKED.error("ELIST2_ITERATOR::add_after_then_move", ABORT);
311 }
312#endif
313
314 if (list->empty()) {
315 new_element->next = new_element;
316 new_element->prev = new_element;
317 list->last = new_element;
318 prev = next = new_element;
319 } else {
320 new_element->next = next;
321 next->prev = new_element;
322
323 if (current) { // not extracted
324 new_element->prev = current;
325 current->next = new_element;
326 prev = current;
327 if (current == list->last) {
328 list->last = new_element;
329 }
330 } else { // current extracted
331 new_element->prev = prev;
332 prev->next = new_element;
333 if (ex_current_was_last) {
334 list->last = new_element;
335 }
336 if (ex_current_was_cycle_pt) {
337 cycle_pt = new_element;
338 }
339 }
340 }
341 current = new_element;
342}
343
344/***********************************************************************
345 * ELIST2_ITERATOR::add_after_stay_put
346 *
347 * Add a new element to the list after the current element but do not move
348 * the iterator to the new element.
349 **********************************************************************/
350
351inline void ELIST2_ITERATOR::add_after_stay_put( // element to add
352 ELIST2_LINK *new_element) {
353#ifndef NDEBUG
354 if (!list) {
355 NO_LIST.error("ELIST2_ITERATOR::add_after_stay_put", ABORT);
356 }
357 if (!new_element) {
358 BAD_PARAMETER.error("ELIST2_ITERATOR::add_after_stay_put", ABORT, "new_element is nullptr");
359 }
360 if (new_element->next) {
361 STILL_LINKED.error("ELIST2_ITERATOR::add_after_stay_put", ABORT);
362 }
363#endif
364
365 if (list->empty()) {
366 new_element->next = new_element;
367 new_element->prev = new_element;
368 list->last = new_element;
369 prev = next = new_element;
370 ex_current_was_last = false;
371 current = nullptr;
372 } else {
373 new_element->next = next;
374 next->prev = new_element;
375
376 if (current) { // not extracted
377 new_element->prev = current;
378 current->next = new_element;
379 if (prev == current) {
380 prev = new_element;
381 }
382 if (current == list->last) {
383 list->last = new_element;
384 }
385 } else { // current extracted
386 new_element->prev = prev;
387 prev->next = new_element;
388 if (ex_current_was_last) {
389 list->last = new_element;
390 ex_current_was_last = false;
391 }
392 }
393 next = new_element;
394 }
395}
396
397/***********************************************************************
398 * ELIST2_ITERATOR::add_before_then_move
399 *
400 * Add a new element to the list before the current element and move the
401 * iterator to the new element.
402 **********************************************************************/
403
404inline void ELIST2_ITERATOR::add_before_then_move( // element to add
405 ELIST2_LINK *new_element) {
406#ifndef NDEBUG
407 if (!list) {
408 NO_LIST.error("ELIST2_ITERATOR::add_before_then_move", ABORT);
409 }
410 if (!new_element) {
411 BAD_PARAMETER.error("ELIST2_ITERATOR::add_before_then_move", ABORT, "new_element is nullptr");
412 }
413 if (new_element->next) {
414 STILL_LINKED.error("ELIST2_ITERATOR::add_before_then_move", ABORT);
415 }
416#endif
417
418 if (list->empty()) {
419 new_element->next = new_element;
420 new_element->prev = new_element;
421 list->last = new_element;
422 prev = next = new_element;
423 } else {
424 prev->next = new_element;
425 new_element->prev = prev;
426
427 if (current) { // not extracted
428 new_element->next = current;
429 current->prev = new_element;
430 next = current;
431 } else { // current extracted
432 new_element->next = next;
433 next->prev = new_element;
434 if (ex_current_was_last) {
435 list->last = new_element;
436 }
437 if (ex_current_was_cycle_pt) {
438 cycle_pt = new_element;
439 }
440 }
441 }
442 current = new_element;
443}
444
445/***********************************************************************
446 * ELIST2_ITERATOR::add_before_stay_put
447 *
448 * Add a new element to the list before the current element but don't move the
449 * iterator to the new element.
450 **********************************************************************/
451
452inline void ELIST2_ITERATOR::add_before_stay_put( // element to add
453 ELIST2_LINK *new_element) {
454#ifndef NDEBUG
455 if (!list) {
456 NO_LIST.error("ELIST2_ITERATOR::add_before_stay_put", ABORT);
457 }
458 if (!new_element) {
459 BAD_PARAMETER.error("ELIST2_ITERATOR::add_before_stay_put", ABORT, "new_element is nullptr");
460 }
461 if (new_element->next) {
462 STILL_LINKED.error("ELIST2_ITERATOR::add_before_stay_put", ABORT);
463 }
464#endif
465
466 if (list->empty()) {
467 new_element->next = new_element;
468 new_element->prev = new_element;
469 list->last = new_element;
470 prev = next = new_element;
471 ex_current_was_last = true;
472 current = nullptr;
473 } else {
474 prev->next = new_element;
475 new_element->prev = prev;
476
477 if (current) { // not extracted
478 new_element->next = current;
479 current->prev = new_element;
480 if (next == current) {
481 next = new_element;
482 }
483 } else { // current extracted
484 new_element->next = next;
485 next->prev = new_element;
486 if (ex_current_was_last) {
487 list->last = new_element;
488 }
489 }
490 prev = new_element;
491 }
492}
493
494/***********************************************************************
495 * ELIST2_ITERATOR::add_list_after
496 *
497 * Insert another list to this list after the current element but don't move
498 *the
499 * iterator.
500 **********************************************************************/
501
502inline void ELIST2_ITERATOR::add_list_after(ELIST2 *list_to_add) {
503#ifndef NDEBUG
504 if (!list) {
505 NO_LIST.error("ELIST2_ITERATOR::add_list_after", ABORT);
506 }
507 if (!list_to_add) {
508 BAD_PARAMETER.error("ELIST2_ITERATOR::add_list_after", ABORT, "list_to_add is nullptr");
509 }
510#endif
511
512 if (!list_to_add->empty()) {
513 if (list->empty()) {
514 list->last = list_to_add->last;
515 prev = list->last;
516 next = list->First();
517 ex_current_was_last = true;
518 current = nullptr;
519 } else {
520 if (current) { // not extracted
521 current->next = list_to_add->First();
522 current->next->prev = current;
523 if (current == list->last) {
524 list->last = list_to_add->last;
525 }
526 list_to_add->last->next = next;
527 next->prev = list_to_add->last;
528 next = current->next;
529 } else { // current extracted
530 prev->next = list_to_add->First();
531 prev->next->prev = prev;
532 if (ex_current_was_last) {
533 list->last = list_to_add->last;
534 ex_current_was_last = false;
535 }
536 list_to_add->last->next = next;
537 next->prev = list_to_add->last;
538 next = prev->next;
539 }
540 }
541 list_to_add->last = nullptr;
542 }
543}
544
545/***********************************************************************
546 * ELIST2_ITERATOR::add_list_before
547 *
548 * Insert another list to this list before the current element. Move the
549 * iterator to the start of the inserted elements
550 * iterator.
551 **********************************************************************/
552
553inline void ELIST2_ITERATOR::add_list_before(ELIST2 *list_to_add) {
554#ifndef NDEBUG
555 if (!list) {
556 NO_LIST.error("ELIST2_ITERATOR::add_list_before", ABORT);
557 }
558 if (!list_to_add) {
559 BAD_PARAMETER.error("ELIST2_ITERATOR::add_list_before", ABORT, "list_to_add is nullptr");
560 }
561#endif
562
563 if (!list_to_add->empty()) {
564 if (list->empty()) {
565 list->last = list_to_add->last;
566 prev = list->last;
567 current = list->First();
568 next = current->next;
569 ex_current_was_last = false;
570 } else {
571 prev->next = list_to_add->First();
572 prev->next->prev = prev;
573
574 if (current) { // not extracted
575 list_to_add->last->next = current;
576 current->prev = list_to_add->last;
577 } else { // current extracted
578 list_to_add->last->next = next;
579 next->prev = list_to_add->last;
580 if (ex_current_was_last) {
581 list->last = list_to_add->last;
582 }
583 if (ex_current_was_cycle_pt) {
584 cycle_pt = prev->next;
585 }
586 }
587 current = prev->next;
588 next = current->next;
589 }
590 list_to_add->last = nullptr;
591 }
592}
593
594/***********************************************************************
595 * ELIST2_ITERATOR::extract
596 *
597 * Do extraction by removing current from the list, returning it to the
598 * caller, but NOT updating the iterator. (So that any calling loop can do
599 * this.) The iterator's current points to nullptr. If the extracted element
600 * is to be deleted, this is the callers responsibility.
601 **********************************************************************/
602
604 ELIST2_LINK *extracted_link;
605
606#ifndef NDEBUG
607 if (!list) {
608 NO_LIST.error("ELIST2_ITERATOR::extract", ABORT);
609 }
610 if (!current) { // list empty or
611 // element extracted
612 NULL_CURRENT.error("ELIST2_ITERATOR::extract", ABORT);
613 }
614#endif
615
616 if (list->singleton()) {
617 // Special case where we do need to change the iterator.
618 prev = next = list->last = nullptr;
619 } else {
620 prev->next = next; // remove from list
621 next->prev = prev;
622
623 if (current == list->last) {
624 list->last = prev;
625 ex_current_was_last = true;
626 } else {
627 ex_current_was_last = false;
628 }
629 }
630 // Always set ex_current_was_cycle_pt so an add/forward will work in a loop.
631 ex_current_was_cycle_pt = (current == cycle_pt);
632 extracted_link = current;
633 extracted_link->next = nullptr; // for safety
634 extracted_link->prev = nullptr; // for safety
635 current = nullptr;
636 return extracted_link;
637}
638
639/***********************************************************************
640 * ELIST2_ITERATOR::move_to_first()
641 *
642 * Move current so that it is set to the start of the list.
643 * Return data just in case anyone wants it.
644 **********************************************************************/
645
647#ifndef NDEBUG
648 if (!list) {
649 NO_LIST.error("ELIST2_ITERATOR::move_to_first", ABORT);
650 }
651#endif
652
653 current = list->First();
654 prev = list->last;
655 next = current ? current->next : nullptr;
656 return current;
657}
658
659/***********************************************************************
660 * ELIST2_ITERATOR::move_to_last()
661 *
662 * Move current so that it is set to the end of the list.
663 * Return data just in case anyone wants it.
664 **********************************************************************/
665
667#ifndef NDEBUG
668 if (!list) {
669 NO_LIST.error("ELIST2_ITERATOR::move_to_last", ABORT);
670 }
671#endif
672
673 current = list->last;
674 prev = current ? current->prev : nullptr;
675 next = current ? current->next : nullptr;
676 return current;
677}
678
679/***********************************************************************
680 * ELIST2_ITERATOR::mark_cycle_pt()
681 *
682 * Remember the current location so that we can tell whether we've returned
683 * to this point later.
684 *
685 * If the current point is deleted either now, or in the future, the cycle
686 * point will be set to the next item which is set to current. This could be
687 * by a forward, add_after_then_move or add_after_then_move.
688 **********************************************************************/
689
691#ifndef NDEBUG
692 if (!list) {
693 NO_LIST.error("ELIST2_ITERATOR::mark_cycle_pt", ABORT);
694 }
695#endif
696
697 if (current) {
698 cycle_pt = current;
699 } else {
700 ex_current_was_cycle_pt = true;
701 }
702 started_cycling = false;
703}
704
705/***********************************************************************
706 * ELIST2_ITERATOR::at_first()
707 *
708 * Are we at the start of the list?
709 *
710 **********************************************************************/
711
712inline bool ELIST2_ITERATOR::at_first() const {
713#ifndef NDEBUG
714 if (!list) {
715 NO_LIST.error("ELIST2_ITERATOR::at_first", ABORT);
716 }
717#endif
718
719 // we're at a deleted
720 return ((list->empty()) || (current == list->First()) ||
721 ((current == nullptr) && (prev == list->last) && // NON-last pt between
722 !ex_current_was_last)); // first and last
723}
724
725/***********************************************************************
726 * ELIST2_ITERATOR::at_last()
727 *
728 * Are we at the end of the list?
729 *
730 **********************************************************************/
731
732inline bool ELIST2_ITERATOR::at_last() const {
733#ifndef NDEBUG
734 if (!list) {
735 NO_LIST.error("ELIST2_ITERATOR::at_last", ABORT);
736 }
737#endif
738
739 // we're at a deleted
740 return ((list->empty()) || (current == list->last) ||
741 ((current == nullptr) && (prev == list->last) && // last point between
742 ex_current_was_last)); // first and last
743}
744
745/***********************************************************************
746 * ELIST2_ITERATOR::cycled_list()
747 *
748 * Have we returned to the cycle_pt since it was set?
749 *
750 **********************************************************************/
751
752inline bool ELIST2_ITERATOR::cycled_list() const {
753#ifndef NDEBUG
754 if (!list) {
755 NO_LIST.error("ELIST2_ITERATOR::cycled_list", ABORT);
756 }
757#endif
758
759 return ((list->empty()) || ((current == cycle_pt) && started_cycling));
760}
761
762/***********************************************************************
763 * ELIST2_ITERATOR::sort()
764 *
765 * Sort the elements of the list, then reposition at the start.
766 *
767 **********************************************************************/
768
769inline void ELIST2_ITERATOR::sort( // sort elements
770 int comparator( // comparison routine
771 const void *, const void *)) {
772#ifndef NDEBUG
773 if (!list) {
774 NO_LIST.error("ELIST2_ITERATOR::sort", ABORT);
775 }
776#endif
777
778 list->sort(comparator);
780}
781
782/***********************************************************************
783 * ELIST2_ITERATOR::add_to_end
784 *
785 * Add a new element to the end of the list without moving the iterator.
786 * This is provided because a single linked list cannot move to the last as
787 * the iterator couldn't set its prev pointer. Adding to the end is
788 * essential for implementing
789 queues.
790**********************************************************************/
791
792inline void ELIST2_ITERATOR::add_to_end( // element to add
793 ELIST2_LINK *new_element) {
794#ifndef NDEBUG
795 if (!list) {
796 NO_LIST.error("ELIST2_ITERATOR::add_to_end", ABORT);
797 }
798 if (!new_element) {
799 BAD_PARAMETER.error("ELIST2_ITERATOR::add_to_end", ABORT, "new_element is nullptr");
800 }
801 if (new_element->next) {
802 STILL_LINKED.error("ELIST2_ITERATOR::add_to_end", ABORT);
803 }
804#endif
805
806 if (this->at_last()) {
807 this->add_after_stay_put(new_element);
808 } else {
809 if (this->at_first()) {
810 this->add_before_stay_put(new_element);
811 list->last = new_element;
812 } else { // Iteratr is elsewhere
813 new_element->next = list->last->next;
814 new_element->prev = list->last;
815 list->last->next->prev = new_element;
816 list->last->next = new_element;
817 list->last = new_element;
818 }
819 }
820}
821
822#define ELIST2IZEH(CLASSNAME) \
823 class CLASSNAME##_LIST : public X_LIST<ELIST2, ELIST2_ITERATOR, CLASSNAME> { \
824 using X_LIST<ELIST2, ELIST2_ITERATOR, CLASSNAME>::X_LIST; \
825 }; \
826 struct CLASSNAME##_IT : X_ITER<ELIST2_ITERATOR, CLASSNAME> { \
827 using X_ITER<ELIST2_ITERATOR, CLASSNAME>::X_ITER; \
828 CLASSNAME *backward() { \
829 return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::backward()); \
830 } \
831 };
832
833} // namespace tesseract
834
835#endif
int * count
LIST last(LIST var_list)
Definition: oldlist.cpp:153
constexpr ERRCODE BAD_PARAMETER("List parameter error")
constexpr ERRCODE STILL_LINKED("Attempting to add an element with non nullptr links, to a list")
constexpr ERRCODE NULL_CURRENT("List current position is nullptr")
constexpr ERRCODE NO_LIST("Iterator not set to a list")
@ ABORT
Definition: errcode.h:31
constexpr ERRCODE NULL_DATA("List would have returned a nullptr data pointer")
def next(obj)
Definition: ast.py:56
ELIST2_LINK(const ELIST2_LINK &)=delete
void operator=(const ELIST2_LINK &)
Definition: elst2.h:75
bool singleton() const
Definition: elst2.h:103
bool empty() const
Definition: elst2.h:99
void sort(int comparator(const void *, const void *))
Definition: elst2.cpp:88
void shallow_copy(ELIST2 *from_list)
Definition: elst2.h:107
void assign_to_sublist(ELIST2_ITERATOR *start_it, ELIST2_ITERATOR *end_it)
Definition: elst2.cpp:68
int32_t length() const
Definition: elst2.h:121
void internal_deep_copy(ELIST2_LINK *(*copier)(ELIST2_LINK *), const ELIST2 *list)
bool at_first() const
Definition: elst2.h:712
void add_after_stay_put(ELIST2_LINK *new_link)
Definition: elst2.h:351
ELIST2_LINK * data()
Definition: elst2.h:191
void add_before_then_move(ELIST2_LINK *new_link)
Definition: elst2.h:404
void add_list_after(ELIST2 *list_to_add)
Definition: elst2.h:502
void add_list_before(ELIST2 *list_to_add)
Definition: elst2.h:553
bool cycled_list() const
Definition: elst2.h:752
ELIST2_LINK * move_to_first()
Definition: elst2.h:646
void add_after_then_move(ELIST2_LINK *new_link)
Definition: elst2.h:300
void sort(int comparator(const void *, const void *))
Definition: elst2.h:769
void set_to_list(ELIST2 *list_to_iterate)
Definition: elst2.h:265
int32_t length() const
Definition: elst2.h:245
ELIST2_LINK * move_to_last()
Definition: elst2.h:666
void add_before_stay_put(ELIST2_LINK *new_link)
Definition: elst2.h:452
void add_to_end(ELIST2_LINK *new_link)
Definition: elst2.h:792
ELIST2_LINK * extract()
Definition: elst2.h:603
bool empty() const
Definition: elst2.h:219
bool current_extracted() const
Definition: elst2.h:228
bool at_last() const
Definition: elst2.h:732
void error(const char *caller, TessErrorLogCode action, const char *format,...) const __attribute__((format(gnu_printf
Definition: errcode.cpp:40
list_rec * next
Definition: oldlist.h:105
#define TESS_API
Definition: export.h:32