tesseract  5.0.0
tesseract::ELIST_ITERATOR Class Reference

#include <elst.h>

Public Member Functions

 ELIST_ITERATOR ()
 
 ELIST_ITERATOR (ELIST *list_to_iterate)
 
void set_to_list (ELIST *list_to_iterate)
 
void add_after_then_move (ELIST_LINK *new_link)
 
void add_after_stay_put (ELIST_LINK *new_link)
 
void add_before_then_move (ELIST_LINK *new_link)
 
void add_before_stay_put (ELIST_LINK *new_link)
 
void add_list_after (ELIST *list_to_add)
 
void add_list_before (ELIST *list_to_add)
 
ELIST_LINKdata ()
 
ELIST_LINKdata_relative (int8_t offset)
 
ELIST_LINKforward ()
 
ELIST_LINKextract ()
 
ELIST_LINKmove_to_first ()
 
ELIST_LINKmove_to_last ()
 
void mark_cycle_pt ()
 
bool empty () const
 
bool current_extracted () const
 
bool at_first () const
 
bool at_last () const
 
bool cycled_list () const
 
void add_to_end (ELIST_LINK *new_link)
 
void exchange (ELIST_ITERATOR *other_it)
 
int32_t length () const
 
void sort (int comparator(const void *, const void *))
 

Friends

void ELIST::assign_to_sublist (ELIST_ITERATOR *, ELIST_ITERATOR *)
 

Detailed Description

Definition at line 188 of file elst.h.

Constructor & Destructor Documentation

◆ ELIST_ITERATOR() [1/2]

tesseract::ELIST_ITERATOR::ELIST_ITERATOR ( )
inline

Definition at line 204 of file elst.h.

204  { // constructor
205  list = nullptr;
206  } // unassigned list

◆ ELIST_ITERATOR() [2/2]

tesseract::ELIST_ITERATOR::ELIST_ITERATOR ( ELIST list_to_iterate)
inlineexplicit

Definition at line 322 of file elst.h.

322  {
323  set_to_list(list_to_iterate);
324 }
void set_to_list(ELIST *list_to_iterate)
Definition: elst.h:298

Member Function Documentation

◆ add_after_stay_put()

void tesseract::ELIST_ITERATOR::add_after_stay_put ( ELIST_LINK new_link)
inline

Definition at line 380 of file elst.h.

381  {
382 #ifndef NDEBUG
383  if (!list) {
384  NO_LIST.error("ELIST_ITERATOR::add_after_stay_put", ABORT, nullptr);
385  }
386  if (!new_element) {
387  BAD_PARAMETER.error("ELIST_ITERATOR::add_after_stay_put", ABORT, "new_element is nullptr");
388  }
389  if (new_element->next) {
390  STILL_LINKED.error("ELIST_ITERATOR::add_after_stay_put", ABORT, nullptr);
391  }
392 #endif
393 
394  if (list->empty()) {
395  new_element->next = new_element;
396  list->last = new_element;
397  prev = next = new_element;
398  ex_current_was_last = false;
399  current = nullptr;
400  } else {
401  new_element->next = next;
402 
403  if (current) { // not extracted
404  current->next = new_element;
405  if (prev == current) {
406  prev = new_element;
407  }
408  if (current == list->last) {
409  list->last = new_element;
410  }
411  } else { // current extracted
412  prev->next = new_element;
413  if (ex_current_was_last) {
414  list->last = new_element;
415  ex_current_was_last = false;
416  }
417  }
418  next = new_element;
419  }
420 }
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 NO_LIST("Iterator not set to a list")
@ ABORT
Definition: errcode.h:31
bool empty() const
Definition: elst.h:124
void error(const char *caller, TessErrorLogCode action, const char *format,...) const __attribute__((format(printf
Definition: errcode.cpp:38

◆ add_after_then_move()

void tesseract::ELIST_ITERATOR::add_after_then_move ( ELIST_LINK new_link)
inline

Definition at line 333 of file elst.h.

334  {
335 #ifndef NDEBUG
336  if (!list) {
337  NO_LIST.error("ELIST_ITERATOR::add_after_then_move", ABORT, nullptr);
338  }
339  if (!new_element) {
340  BAD_PARAMETER.error("ELIST_ITERATOR::add_after_then_move", ABORT, "new_element is nullptr");
341  }
342  if (new_element->next) {
343  STILL_LINKED.error("ELIST_ITERATOR::add_after_then_move", ABORT, nullptr);
344  }
345 #endif
346 
347  if (list->empty()) {
348  new_element->next = new_element;
349  list->last = new_element;
350  prev = next = new_element;
351  } else {
352  new_element->next = next;
353 
354  if (current) { // not extracted
355  current->next = new_element;
356  prev = current;
357  if (current == list->last) {
358  list->last = new_element;
359  }
360  } else { // current extracted
361  prev->next = new_element;
362  if (ex_current_was_last) {
363  list->last = new_element;
364  }
365  if (ex_current_was_cycle_pt) {
366  cycle_pt = new_element;
367  }
368  }
369  }
370  current = new_element;
371 }

◆ add_before_stay_put()

void tesseract::ELIST_ITERATOR::add_before_stay_put ( ELIST_LINK new_link)
inline

Definition at line 472 of file elst.h.

473  {
474 #ifndef NDEBUG
475  if (!list) {
476  NO_LIST.error("ELIST_ITERATOR::add_before_stay_put", ABORT, nullptr);
477  }
478  if (!new_element) {
479  BAD_PARAMETER.error("ELIST_ITERATOR::add_before_stay_put", ABORT, "new_element is nullptr");
480  }
481  if (new_element->next) {
482  STILL_LINKED.error("ELIST_ITERATOR::add_before_stay_put", ABORT, nullptr);
483  }
484 #endif
485 
486  if (list->empty()) {
487  new_element->next = new_element;
488  list->last = new_element;
489  prev = next = new_element;
490  ex_current_was_last = true;
491  current = nullptr;
492  } else {
493  prev->next = new_element;
494  if (current) { // not extracted
495  new_element->next = current;
496  if (next == current) {
497  next = new_element;
498  }
499  } else { // current extracted
500  new_element->next = next;
501  if (ex_current_was_last) {
502  list->last = new_element;
503  }
504  }
505  prev = new_element;
506  }
507 }

◆ add_before_then_move()

void tesseract::ELIST_ITERATOR::add_before_then_move ( ELIST_LINK new_link)
inline

Definition at line 429 of file elst.h.

430  {
431 #ifndef NDEBUG
432  if (!list) {
433  NO_LIST.error("ELIST_ITERATOR::add_before_then_move", ABORT, nullptr);
434  }
435  if (!new_element) {
436  BAD_PARAMETER.error("ELIST_ITERATOR::add_before_then_move", ABORT, "new_element is nullptr");
437  }
438  if (new_element->next) {
439  STILL_LINKED.error("ELIST_ITERATOR::add_before_then_move", ABORT, nullptr);
440  }
441 #endif
442 
443  if (list->empty()) {
444  new_element->next = new_element;
445  list->last = new_element;
446  prev = next = new_element;
447  } else {
448  prev->next = new_element;
449  if (current) { // not extracted
450  new_element->next = current;
451  next = current;
452  } else { // current extracted
453  new_element->next = next;
454  if (ex_current_was_last) {
455  list->last = new_element;
456  }
457  if (ex_current_was_cycle_pt) {
458  cycle_pt = new_element;
459  }
460  }
461  }
462  current = new_element;
463 }

◆ add_list_after()

void tesseract::ELIST_ITERATOR::add_list_after ( ELIST list_to_add)
inline

Definition at line 517 of file elst.h.

517  {
518 #ifndef NDEBUG
519  if (!list) {
520  NO_LIST.error("ELIST_ITERATOR::add_list_after", ABORT, nullptr);
521  }
522  if (!list_to_add) {
523  BAD_PARAMETER.error("ELIST_ITERATOR::add_list_after", ABORT, "list_to_add is nullptr");
524  }
525 #endif
526 
527  if (!list_to_add->empty()) {
528  if (list->empty()) {
529  list->last = list_to_add->last;
530  prev = list->last;
531  next = list->First();
532  ex_current_was_last = true;
533  current = nullptr;
534  } else {
535  if (current) { // not extracted
536  current->next = list_to_add->First();
537  if (current == list->last) {
538  list->last = list_to_add->last;
539  }
540  list_to_add->last->next = next;
541  next = current->next;
542  } else { // current extracted
543  prev->next = list_to_add->First();
544  if (ex_current_was_last) {
545  list->last = list_to_add->last;
546  ex_current_was_last = false;
547  }
548  list_to_add->last->next = next;
549  next = prev->next;
550  }
551  }
552  list_to_add->last = nullptr;
553  }
554 }

◆ add_list_before()

void tesseract::ELIST_ITERATOR::add_list_before ( ELIST list_to_add)
inline

Definition at line 564 of file elst.h.

564  {
565 #ifndef NDEBUG
566  if (!list) {
567  NO_LIST.error("ELIST_ITERATOR::add_list_before", ABORT, nullptr);
568  }
569  if (!list_to_add) {
570  BAD_PARAMETER.error("ELIST_ITERATOR::add_list_before", ABORT, "list_to_add is nullptr");
571  }
572 #endif
573 
574  if (!list_to_add->empty()) {
575  if (list->empty()) {
576  list->last = list_to_add->last;
577  prev = list->last;
578  current = list->First();
579  next = current->next;
580  ex_current_was_last = false;
581  } else {
582  prev->next = list_to_add->First();
583  if (current) { // not extracted
584  list_to_add->last->next = current;
585  } else { // current extracted
586  list_to_add->last->next = next;
587  if (ex_current_was_last) {
588  list->last = list_to_add->last;
589  }
590  if (ex_current_was_cycle_pt) {
591  cycle_pt = prev->next;
592  }
593  }
594  current = prev->next;
595  next = current->next;
596  }
597  list_to_add->last = nullptr;
598  }
599 }

◆ add_to_end()

void tesseract::ELIST_ITERATOR::add_to_end ( ELIST_LINK new_link)
inline

Definition at line 775 of file elst.h.

776  {
777 #ifndef NDEBUG
778  if (!list) {
779  NO_LIST.error("ELIST_ITERATOR::add_to_end", ABORT, nullptr);
780  }
781  if (!new_element) {
782  BAD_PARAMETER.error("ELIST_ITERATOR::add_to_end", ABORT, "new_element is nullptr");
783  }
784  if (new_element->next) {
785  STILL_LINKED.error("ELIST_ITERATOR::add_to_end", ABORT, nullptr);
786  }
787 #endif
788 
789  if (this->at_last()) {
790  this->add_after_stay_put(new_element);
791  } else {
792  if (this->at_first()) {
793  this->add_before_stay_put(new_element);
794  list->last = new_element;
795  } else { // Iteratr is elsewhere
796  new_element->next = list->last->next;
797  list->last->next = new_element;
798  list->last = new_element;
799  }
800  }
801 }
void add_after_stay_put(ELIST_LINK *new_link)
Definition: elst.h:380
bool at_last() const
Definition: elst.h:715
void add_before_stay_put(ELIST_LINK *new_link)
Definition: elst.h:472
bool at_first() const
Definition: elst.h:695

◆ at_first()

bool tesseract::ELIST_ITERATOR::at_first ( ) const
inline

Definition at line 695 of file elst.h.

695  {
696 #ifndef NDEBUG
697  if (!list) {
698  NO_LIST.error("ELIST_ITERATOR::at_first", ABORT, nullptr);
699  }
700 #endif
701 
702  // we're at a deleted
703  return ((list->empty()) || (current == list->First()) ||
704  ((current == nullptr) && (prev == list->last) && // NON-last pt between
705  !ex_current_was_last)); // first and last
706 }

◆ at_last()

bool tesseract::ELIST_ITERATOR::at_last ( ) const
inline

Definition at line 715 of file elst.h.

715  {
716 #ifndef NDEBUG
717  if (!list) {
718  NO_LIST.error("ELIST_ITERATOR::at_last", ABORT, nullptr);
719  }
720 #endif
721 
722  // we're at a deleted
723  return ((list->empty()) || (current == list->last) ||
724  ((current == nullptr) && (prev == list->last) && // last point between
725  ex_current_was_last)); // first and last
726 }

◆ current_extracted()

bool tesseract::ELIST_ITERATOR::current_extracted ( ) const
inline

Definition at line 265 of file elst.h.

265  { // current extracted?
266  return !current;
267  }

◆ cycled_list()

bool tesseract::ELIST_ITERATOR::cycled_list ( ) const
inline

Definition at line 735 of file elst.h.

735  {
736 #ifndef NDEBUG
737  if (!list) {
738  NO_LIST.error("ELIST_ITERATOR::cycled_list", ABORT, nullptr);
739  }
740 #endif
741 
742  return ((list->empty()) || ((current == cycle_pt) && started_cycling));
743 }

◆ data()

ELIST_LINK* tesseract::ELIST_ITERATOR::data ( )
inline

Definition at line 231 of file elst.h.

231  { // get current data
232 #ifndef NDEBUG
233  if (!list) {
234  NO_LIST.error("ELIST_ITERATOR::data", ABORT, nullptr);
235  }
236  if (!current) {
237  NULL_DATA.error("ELIST_ITERATOR::data", ABORT, nullptr);
238  }
239 #endif
240  return current;
241  }
constexpr ERRCODE NULL_DATA("List would have returned a nullptr data pointer")

◆ data_relative()

ELIST_LINK * tesseract::ELIST_ITERATOR::data_relative ( int8_t  offset)

Definition at line 211 of file elst.cpp.

212  { // offset from current
213  ELIST_LINK *ptr;
214 
215 #ifndef NDEBUG
216  if (!list)
217  NO_LIST.error("ELIST_ITERATOR::data_relative", ABORT, nullptr);
218  if (list->empty())
219  EMPTY_LIST.error("ELIST_ITERATOR::data_relative", ABORT, nullptr);
220  if (offset < -1)
221  BAD_PARAMETER.error("ELIST_ITERATOR::data_relative", ABORT, "offset < -l");
222 #endif
223 
224  if (offset == -1) {
225  ptr = prev;
226  } else {
227  for (ptr = current ? current : prev; offset-- > 0; ptr = ptr->next) {
228  ;
229  }
230  }
231 
232 #ifndef NDEBUG
233  if (!ptr)
234  NULL_DATA.error("ELIST_ITERATOR::data_relative", ABORT, nullptr);
235 #endif
236 
237  return ptr;
238 }
constexpr ERRCODE EMPTY_LIST("List is empty")

◆ empty()

bool tesseract::ELIST_ITERATOR::empty ( ) const
inline

Definition at line 256 of file elst.h.

256  { // is list empty?
257 #ifndef NDEBUG
258  if (!list) {
259  NO_LIST.error("ELIST_ITERATOR::empty", ABORT, nullptr);
260  }
261 #endif
262  return list->empty();
263  }

◆ exchange()

void tesseract::ELIST_ITERATOR::exchange ( ELIST_ITERATOR other_it)

Definition at line 271 of file elst.cpp.

272  { // other iterator
273  constexpr ERRCODE DONT_EXCHANGE_DELETED("Can't exchange deleted elements of lists");
274 
275  ELIST_LINK *old_current;
276 
277 #ifndef NDEBUG
278  if (!list)
279  NO_LIST.error("ELIST_ITERATOR::exchange", ABORT, nullptr);
280  if (!other_it)
281  BAD_PARAMETER.error("ELIST_ITERATOR::exchange", ABORT, "other_it nullptr");
282  if (!(other_it->list))
283  NO_LIST.error("ELIST_ITERATOR::exchange", ABORT, "other_it");
284 #endif
285 
286  /* Do nothing if either list is empty or if both iterators reference the same
287 link */
288 
289  if ((list->empty()) || (other_it->list->empty()) || (current == other_it->current)) {
290  return;
291  }
292 
293  /* Error if either current element is deleted */
294 
295  if (!current || !other_it->current) {
296  DONT_EXCHANGE_DELETED.error("ELIST_ITERATOR.exchange", ABORT, nullptr);
297  }
298 
299  /* Now handle the 4 cases: doubleton list; non-doubleton adjacent elements
300 (other before this); non-doubleton adjacent elements (this before other);
301 non-adjacent elements. */
302 
303  // adjacent links
304  if ((next == other_it->current) || (other_it->next == current)) {
305  // doubleton list
306  if ((next == other_it->current) && (other_it->next == current)) {
307  prev = next = current;
308  other_it->prev = other_it->next = other_it->current;
309  } else { // non-doubleton with
310  // adjacent links
311  // other before this
312  if (other_it->next == current) {
313  other_it->prev->next = current;
314  other_it->current->next = next;
315  current->next = other_it->current;
316  other_it->next = other_it->current;
317  prev = current;
318  } else { // this before other
319  prev->next = other_it->current;
320  current->next = other_it->next;
321  other_it->current->next = current;
322  next = current;
323  other_it->prev = other_it->current;
324  }
325  }
326  } else { // no overlap
327  prev->next = other_it->current;
328  current->next = other_it->next;
329  other_it->prev->next = current;
330  other_it->current->next = next;
331  }
332 
333  /* update end of list pointer when necessary (remember that the 2 iterators
334  may iterate over different lists!) */
335 
336  if (list->last == current) {
337  list->last = other_it->current;
338  }
339  if (other_it->list->last == other_it->current) {
340  other_it->list->last = current;
341  }
342 
343  if (current == cycle_pt) {
344  cycle_pt = other_it->cycle_pt;
345  }
346  if (other_it->current == other_it->cycle_pt) {
347  other_it->cycle_pt = cycle_pt;
348  }
349 
350  /* The actual exchange - in all cases*/
351 
352  old_current = current;
353  current = other_it->current;
354  other_it->current = old_current;
355 }

◆ extract()

ELIST_LINK * tesseract::ELIST_ITERATOR::extract ( )
inline

Definition at line 610 of file elst.h.

610  {
611  ELIST_LINK *extracted_link;
612 
613 #ifndef NDEBUG
614  if (!list) {
615  NO_LIST.error("ELIST_ITERATOR::extract", ABORT, nullptr);
616  }
617  if (!current) { // list empty or
618  // element extracted
619  NULL_CURRENT.error("ELIST_ITERATOR::extract", ABORT, nullptr);
620  }
621 #endif
622 
623  if (list->singleton()) {
624  // Special case where we do need to change the iterator.
625  prev = next = list->last = nullptr;
626  } else {
627  prev->next = next; // remove from list
628 
629  ex_current_was_last = (current == list->last);
630  if (ex_current_was_last) {
631  list->last = prev;
632  }
633  }
634  // Always set ex_current_was_cycle_pt so an add/forward will work in a loop.
635  ex_current_was_cycle_pt = (current == cycle_pt);
636  extracted_link = current;
637  extracted_link->next = nullptr; // for safety
638  current = nullptr;
639  return extracted_link;
640 }
constexpr ERRCODE NULL_CURRENT("List current position is nullptr")
bool singleton() const
Definition: elst.h:128

◆ forward()

ELIST_LINK * tesseract::ELIST_ITERATOR::forward ( )

Definition at line 169 of file elst.cpp.

169  {
170 #ifndef NDEBUG
171  if (!list)
172  NO_LIST.error("ELIST_ITERATOR::forward", ABORT, nullptr);
173 #endif
174  if (list->empty()) {
175  return nullptr;
176  }
177 
178  if (current) { // not removed so
179  // set previous
180  prev = current;
181  started_cycling = true;
182  // In case next is deleted by another iterator, get next from current.
183  current = current->next;
184  } else {
185  if (ex_current_was_cycle_pt) {
186  cycle_pt = next;
187  }
188  current = next;
189  }
190 #ifndef NDEBUG
191  if (!current)
192  NULL_DATA.error("ELIST_ITERATOR::forward", ABORT, nullptr);
193 #endif
194  next = current->next;
195 
196 #ifndef NDEBUG
197  if (!next)
198  NULL_NEXT.error("ELIST_ITERATOR::forward", ABORT, "This is: %p Current is: %p", this, current);
199 #endif
200  return current;
201 }
constexpr ERRCODE NULL_NEXT("Next element on the list is nullptr")

◆ length()

int32_t tesseract::ELIST_ITERATOR::length ( ) const
inline

Definition at line 282 of file elst.h.

282  {
283  return list->length();
284  }
int32_t length() const
Definition: elst.h:146

◆ mark_cycle_pt()

void tesseract::ELIST_ITERATOR::mark_cycle_pt ( )
inline

Definition at line 673 of file elst.h.

673  {
674 #ifndef NDEBUG
675  if (!list) {
676  NO_LIST.error("ELIST_ITERATOR::mark_cycle_pt", ABORT, nullptr);
677  }
678 #endif
679 
680  if (current) {
681  cycle_pt = current;
682  } else {
683  ex_current_was_cycle_pt = true;
684  }
685  started_cycling = false;
686 }

◆ move_to_first()

ELIST_LINK * tesseract::ELIST_ITERATOR::move_to_first ( )
inline

Definition at line 649 of file elst.h.

649  {
650 #ifndef NDEBUG
651  if (!list) {
652  NO_LIST.error("ELIST_ITERATOR::move_to_first", ABORT, nullptr);
653  }
654 #endif
655 
656  current = list->First();
657  prev = list->last;
658  next = current ? current->next : nullptr;
659  return current;
660 }

◆ move_to_last()

ELIST_LINK * tesseract::ELIST_ITERATOR::move_to_last ( )

Definition at line 248 of file elst.cpp.

248  {
249 #ifndef NDEBUG
250  if (!list)
251  NO_LIST.error("ELIST_ITERATOR::move_to_last", ABORT, nullptr);
252 #endif
253 
254  while (current != list->last) {
255  forward();
256  }
257 
258  return current;
259 }
ELIST_LINK * forward()
Definition: elst.cpp:169

◆ set_to_list()

void tesseract::ELIST_ITERATOR::set_to_list ( ELIST list_to_iterate)
inline

Definition at line 298 of file elst.h.

299  {
300 #ifndef NDEBUG
301  if (!list_to_iterate) {
302  BAD_PARAMETER.error("ELIST_ITERATOR::set_to_list", ABORT, "list_to_iterate is nullptr");
303  }
304 #endif
305 
306  list = list_to_iterate;
307  prev = list->last;
308  current = list->First();
309  next = current ? current->next : nullptr;
310  cycle_pt = nullptr; // await explicit set
311  started_cycling = false;
312  ex_current_was_last = false;
313  ex_current_was_cycle_pt = false;
314 }

◆ sort()

void tesseract::ELIST_ITERATOR::sort ( int   comparator const void *, const void *)
inline

Definition at line 752 of file elst.h.

754  {
755 #ifndef NDEBUG
756  if (!list) {
757  NO_LIST.error("ELIST_ITERATOR::sort", ABORT, nullptr);
758  }
759 #endif
760 
761  list->sort(comparator);
762  move_to_first();
763 }
void sort(int comparator(const void *, const void *))
Definition: elst.cpp:87
ELIST_LINK * move_to_first()
Definition: elst.h:649

Friends And Related Function Documentation

◆ ELIST::assign_to_sublist


The documentation for this class was generated from the following files: