Commit 9d40512a for tesseract

commit 9d40512ade516e0bb45090db8b5c7a7028de8c54
Author: Egor Pugin <egor.pugin@gmail.com>
Date:   Wed Apr 7 00:15:01 2021 +0300

    [elist2] Convert macros to template. Remove source file macro ELIST2IZE.

diff --git a/src/ccstruct/blobbox.cpp b/src/ccstruct/blobbox.cpp
index 83bb7253..a452b7b8 100644
--- a/src/ccstruct/blobbox.cpp
+++ b/src/ccstruct/blobbox.cpp
@@ -39,8 +39,6 @@

 namespace tesseract {

-ELIST2IZE(TO_ROW)
-
 // Up to 30 degrees is allowed for rotations of diacritic blobs.
 const double kCosSmallAngle = 0.866;
 // Min aspect ratio for a joined word to indicate an obvious flow direction.
diff --git a/src/ccstruct/werd.cpp b/src/ccstruct/werd.cpp
index ad54d888..12932fa3 100644
--- a/src/ccstruct/werd.cpp
+++ b/src/ccstruct/werd.cpp
@@ -33,8 +33,6 @@ namespace tesseract {
 #define LAST_COLOUR ScrollView::AQUAMARINE ///< last rainbow colour
 #define CHILD_COLOUR ScrollView::BROWN     ///< colour of children

-ELIST2IZE(WERD)
-
 /**
  * WERD::WERD
  *
diff --git a/src/ccutil/clst.h b/src/ccutil/clst.h
index b216f878..caa22e1c 100644
--- a/src/ccutil/clst.h
+++ b/src/ccutil/clst.h
@@ -19,7 +19,7 @@
 #ifndef CLST_H
 #define CLST_H

-#include "list_iterator.h"
+#include "list.h"
 #include "lsterr.h"
 #include "serialis.h"

diff --git a/src/ccutil/elst.cpp b/src/ccutil/elst.cpp
index c884dbab..4ee9e733 100644
--- a/src/ccutil/elst.cpp
+++ b/src/ccutil/elst.cpp
@@ -34,7 +34,7 @@ namespace tesseract {
  **********************************************************************/

 void ELIST::internal_clear( // destroy all links
-    void (*zapper)(ELIST_LINK *)) {
+    void (*zapper)(void *)) {
   // ptr to zapper functn
   ELIST_LINK *ptr;
   ELIST_LINK *next;
diff --git a/src/ccutil/elst.h b/src/ccutil/elst.h
index 6f4bf28b..8f79f1a0 100644
--- a/src/ccutil/elst.h
+++ b/src/ccutil/elst.h
@@ -19,7 +19,7 @@
 #ifndef ELST_H
 #define ELST_H

-#include "list_iterator.h"
+#include "list.h"
 #include "lsterr.h"
 #include "serialis.h"

@@ -124,7 +124,7 @@ public:

   void internal_clear( // destroy all links
                        // ptr to zapper functn
-      void (*zapper)(ELIST_LINK *));
+      void (*zapper)(void *));

   bool empty() const { // is list empty?
     return !last;
@@ -805,43 +805,15 @@ inline void ELIST_ITERATOR::add_to_end( // element to add
   }
 }

-template <typename CLASSNAME>
-class X_LIST : public ELIST {
-public:
-  X_LIST() = default;
-  X_LIST(const X_LIST &) = delete;
-  X_LIST &operator=(const X_LIST &) = delete;
-  ~X_LIST() {
-    clear();
-  }
-
-  /* delete elements */
-  void clear() {
-    ELIST::internal_clear([](ELIST_LINK *link) {delete reinterpret_cast<CLASSNAME *>(link);});
-  }
-
-  /* Become a deep copy of src_list */
-  template <typename U>
-  void deep_copy(const U *src_list, CLASSNAME *(*copier)(const CLASSNAME *)) {
-    static_assert(std::is_base_of_v<X_LIST, U>);
-
-    X_ITER<ELIST_ITERATOR, CLASSNAME> from_it(const_cast<U *>(src_list));
-    X_ITER<ELIST_ITERATOR, CLASSNAME> to_it(this);
-
-    for (from_it.mark_cycle_pt(); !from_it.cycled_list(); from_it.forward())
-      to_it.add_after_then_move((*copier)(from_it.data()));
-  }
-};
-
-#define ELISTIZEH(CLASSNAME)                                        \
-  class CLASSNAME##_LIST : public X_LIST<CLASSNAME> {               \
-  public:                                                           \
-    using X_LIST<CLASSNAME>::X_LIST;                                \
-  };                                                                \
-  class CLASSNAME##_IT : public X_ITER<ELIST_ITERATOR, CLASSNAME> { \
-  public:                                                           \
-    using X_ITER<ELIST_ITERATOR, CLASSNAME>::X_ITER;                \
-    CLASSNAME##_IT(CLASSNAME##_LIST *list) : X_ITER(list) {}        \
+#define ELISTIZEH(CLASSNAME)                                                 \
+  class CLASSNAME##_LIST : public X_LIST<ELIST, ELIST_ITERATOR, CLASSNAME> { \
+  public:                                                                    \
+    using X_LIST<ELIST, ELIST_ITERATOR, CLASSNAME>::X_LIST;                  \
+  };                                                                         \
+  class CLASSNAME##_IT : public X_ITER<ELIST_ITERATOR, CLASSNAME> {          \
+  public:                                                                    \
+    using X_ITER<ELIST_ITERATOR, CLASSNAME>::X_ITER;                         \
+    CLASSNAME##_IT(CLASSNAME##_LIST *list) : X_ITER(list) {}                 \
   };

 } // namespace tesseract
diff --git a/src/ccutil/elst2.cpp b/src/ccutil/elst2.cpp
index a8b1357f..22ef6d9f 100644
--- a/src/ccutil/elst2.cpp
+++ b/src/ccutil/elst2.cpp
@@ -35,7 +35,7 @@ namespace tesseract {
  **********************************************************************/

 void ELIST2::internal_clear( // destroy all links
-    void (*zapper)(ELIST2_LINK *)) {
+    void (*zapper)(void *)) {
   // ptr to zapper functn
   ELIST2_LINK *ptr;
   ELIST2_LINK *next;
diff --git a/src/ccutil/elst2.h b/src/ccutil/elst2.h
index 8858a681..5f494d8d 100644
--- a/src/ccutil/elst2.h
+++ b/src/ccutil/elst2.h
@@ -19,6 +19,7 @@
 #ifndef ELST2_H
 #define ELST2_H

+#include "list.h"
 #include "lsterr.h"
 #include "serialis.h"

@@ -97,7 +98,7 @@ public:
   }

   void internal_clear( // destroy all links
-      void (*zapper)(ELIST2_LINK *));
+      void (*zapper)(void *));
   // ptr to zapper functn

   bool empty() const { // is list empty?
@@ -823,149 +824,20 @@ inline void ELIST2_ITERATOR::add_to_end( // element to add
   }
 }

-/***********************************************************************
-  ELIST2IZE(CLASSNAME) MACRO DEFINITION
-  ======================================
-
-CLASSNAME is assumed to be the name of a class which has a baseclass of
-ELIST2_LINK.
-
-NOTE:  Because we don't use virtual functions in the list code, the list code
-will NOT work correctly for classes derived from this.
-
-The macro generates:
-  - An element deletion function:      CLASSNAME##_zapper
-  - An E_LIST2 subclass:  CLASSNAME##_LIST
-  - An E_LIST2_ITERATOR subclass:
-              CLASSNAME##_IT
-
-NOTE: Generated names are DELIBERATELY designed to clash with those for
-ELISTIZE but NOT with those for CLISTIZE.
-
-Two macros are provided: ELIST2IZE and ELIST2IZEH
-The ...IZEH macros just define the class names for use in .h files
-The ...IZE macros define the code use in .c files
-***********************************************************************/
-
-/***********************************************************************
-  ELIST2IZEH(CLASSNAME) MACRO
-
-ELIST2IZEH is a concatenation of 3 fragments ELIST2IZEH_A, ELIST2IZEH_B and
-ELIST2IZEH_C.
-***********************************************************************/
-
-#define ELIST2IZEH_A(CLASSNAME)                                                 \
-                                                                                \
-  TESS_API extern void CLASSNAME##_zapper(                    /*delete a link*/ \
-                                          ELIST2_LINK *link); /*link to delete*/
-
-#define ELIST2IZEH_B(CLASSNAME)                                                                \
-                                                                                               \
-  /***********************************************************************                     \
-   *             CLASS -                                                                       \
-   *CLASSNAME##_LIST                                                                           \
-   *                                                                                           \
-   *             List class for class                                                          \
-   *CLASSNAME                                                                                  \
-   *                                                                                           \
-   **********************************************************************/                     \
-                                                                                               \
-  class CLASSNAME##_LIST : public ELIST2 {                                                     \
-  public:                                                                                      \
-    CLASSNAME##_LIST() : ELIST2() {}                                                           \
-    /* constructor */                                                                          \
-                                                                                               \
-    CLASSNAME##_LIST(const CLASSNAME##_LIST &) = delete;                                       \
-    void operator=(const CLASSNAME##_LIST &) = delete;                                         \
-                                                                                               \
-    void clear() /* delete elements */                                                         \
-    {                                                                                          \
-      ELIST2::internal_clear(&CLASSNAME##_zapper);                                             \
-    }                                                                                          \
-                                                                                               \
-    ~CLASSNAME##_LIST() /* destructor */                                                       \
-    {                                                                                          \
-      clear();                                                                                 \
-    }                                                                                          \
-                                                                                               \
-    /* Become a deep copy of src_list*/                                                        \
-    void deep_copy(const CLASSNAME##_LIST *src_list, CLASSNAME *(*copier)(const CLASSNAME *)); \
-
-#define ELIST2IZEH_C(CLASSNAME)                                                     \
-  }                                                                                 \
-  ;                                                                                 \
-                                                                                    \
-  /***********************************************************************          \
-   *             CLASS - CLASSNAME##_IT                                             \
-   *                                                                                \
-   *             Iterator class for class CLASSNAME##_LIST                          \
-   *                                                                                \
-   *  Note: We don't need to coerce pointers to member functions input              \
-   *  parameters as these are automatically converted to the type of the base       \
-   *  type. ("A ptr to a class may be converted to a pointer to a public base       \
-   *  class of that class")                                                         \
-   **********************************************************************/          \
-                                                                                    \
-  class CLASSNAME##_IT : public ELIST2_ITERATOR {                                   \
-  public:                                                                           \
-    CLASSNAME##_IT(CLASSNAME##_LIST *list) : ELIST2_ITERATOR(list) {}               \
-                                                                                    \
-    CLASSNAME *data() {                                                             \
-      return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::data());                \
-    }                                                                               \
-    CLASSNAME *data_relative(int8_t offset) {                                       \
-      return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::data_relative(offset)); \
-    }                                                                               \
-    CLASSNAME *forward() {                                                          \
-      return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::forward());             \
-    }                                                                               \
-    CLASSNAME *backward() {                                                         \
-      return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::backward());            \
-    }                                                                               \
-    CLASSNAME *extract() {                                                          \
-      return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::extract());             \
-    }                                                                               \
-                                                                                    \
-  private:                                                                          \
-    CLASSNAME##_IT();                                                               \
+#define ELIST2IZEH(CLASSNAME)                                                 \
+  class CLASSNAME##_LIST : public X_LIST<ELIST2, ELIST2_ITERATOR, CLASSNAME> { \
+  public:                                                                      \
+    using X_LIST<ELIST2, ELIST2_ITERATOR, CLASSNAME>::X_LIST;                  \
+  };                                                                           \
+  class CLASSNAME##_IT : public X_ITER<ELIST2_ITERATOR, CLASSNAME> {           \
+  public:                                                                      \
+    using X_ITER<ELIST2_ITERATOR, CLASSNAME>::X_ITER;                          \
+    CLASSNAME##_IT(CLASSNAME##_LIST *list) : X_ITER(list) {}                   \
+    CLASSNAME *backward() {                                                    \
+      return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::backward());       \
+    }                                                                          \
   };

-#define ELIST2IZEH(CLASSNAME) \
-  ELIST2IZEH_A(CLASSNAME)     \
-  ELIST2IZEH_B(CLASSNAME)     \
-  ELIST2IZEH_C(CLASSNAME)
-
-/***********************************************************************
-  ELIST2IZE(CLASSNAME) MACRO
-***********************************************************************/
-
-#define ELIST2IZE(CLASSNAME)                                                  \
-                                                                              \
-  /***********************************************************************    \
-   *             CLASSNAME##_zapper                                           \
-   *                                                                          \
-   *  A function which can delete a CLASSNAME element.  This is passed to the \
-   *  generic clear list member function so that when a list is cleared the   \
-   *  elements on the list are properly destroyed from the base class, even   \
-   *  though we don't use a virtual destructor function.                      \
-   **********************************************************************/    \
-                                                                              \
-  void CLASSNAME##_zapper(                   /*delete a link*/                \
-                          ELIST2_LINK *link) /*link to delete*/               \
-  {                                                                           \
-    delete reinterpret_cast<CLASSNAME *>(link);                               \
-  }                                                                           \
-                                                                              \
-  /* Become a deep copy of src_list*/                                         \
-  void CLASSNAME##_LIST::deep_copy(const CLASSNAME##_LIST *src_list,          \
-                                   CLASSNAME *(*copier)(const CLASSNAME *)) { \
-    CLASSNAME##_IT from_it(const_cast<CLASSNAME##_LIST *>(src_list));         \
-    CLASSNAME##_IT to_it(this);                                               \
-                                                                              \
-    for (from_it.mark_cycle_pt(); !from_it.cycled_list(); from_it.forward())  \
-      to_it.add_after_then_move((*copier)(from_it.data()));                   \
-  }
-
 } // namespace tesseract

 #endif
diff --git a/src/ccutil/list_iterator.h b/src/ccutil/list.h
similarity index 61%
rename from src/ccutil/list_iterator.h
rename to src/ccutil/list.h
index c419ed20..ac773c75 100644
--- a/src/ccutil/list_iterator.h
+++ b/src/ccutil/list.h
@@ -18,6 +18,34 @@

 namespace tesseract {

+template <typename CONTAINER, typename ITERATOR_TYPE, typename CLASSNAME>
+class X_LIST : public CONTAINER {
+public:
+  X_LIST() = default;
+  X_LIST(const X_LIST &) = delete;
+  X_LIST &operator=(const X_LIST &) = delete;
+  ~X_LIST() {
+    clear();
+  }
+
+  /* delete elements */
+  void clear() {
+    CONTAINER::internal_clear([](void *link) {delete reinterpret_cast<CLASSNAME *>(link);});
+  }
+
+  /* Become a deep copy of src_list */
+  template <typename U>
+  void deep_copy(const U *src_list, CLASSNAME *(*copier)(const CLASSNAME *)) {
+    static_assert(std::is_base_of_v<X_LIST, U>);
+
+    X_ITER<ITERATOR_TYPE, CLASSNAME> from_it(const_cast<U *>(src_list));
+    X_ITER<ITERATOR_TYPE, CLASSNAME> to_it(this);
+
+    for (from_it.mark_cycle_pt(); !from_it.cycled_list(); from_it.forward())
+      to_it.add_after_then_move((*copier)(from_it.data()));
+  }
+};
+
 template <typename CONTAINER, typename CLASSNAME>
 class X_ITER : public CONTAINER {
 public:
diff --git a/src/textord/colpartition.cpp b/src/textord/colpartition.cpp
index fcef29fe..933978d7 100644
--- a/src/textord/colpartition.cpp
+++ b/src/textord/colpartition.cpp
@@ -35,8 +35,6 @@

 namespace tesseract {

-ELIST2IZE(ColPartition)
-
 //////////////// ColPartition Implementation ////////////////

 // enum to refer to the entries in a neighbourhood of lines.
diff --git a/src/textord/tabvector.cpp b/src/textord/tabvector.cpp
index bc9ff596..771a5f0d 100644
--- a/src/textord/tabvector.cpp
+++ b/src/textord/tabvector.cpp
@@ -163,8 +163,6 @@ void TabConstraint::GetConstraints(TabConstraint_LIST *constraints, int *y_min,
   }
 }

-ELIST2IZE(TabVector)
-
 // The constructor is private. See the bottom of the file...

 // Public factory to build a TabVector from a list of boxes.
diff --git a/unittest/list_test.cc b/unittest/list_test.cc
index 04d8c343..212994e4 100644
--- a/unittest/list_test.cc
+++ b/unittest/list_test.cc
@@ -46,7 +46,6 @@ public:
 CLISTIZEH(Clst)
 ELISTIZEH(Elst)
 ELIST2IZEH(Elst2)
-ELIST2IZE(Elst2)

 TEST_F(ListTest, TestCLIST) {
   Clst_CLIST list;