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

This commit is contained in:
Egor Pugin 2021-04-07 00:15:01 +03:00
parent 03435adca0
commit 9d40512ade
11 changed files with 56 additions and 193 deletions

View File

@ -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.

View File

@ -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
*

View File

@ -19,7 +19,7 @@
#ifndef CLST_H
#define CLST_H
#include "list_iterator.h"
#include "list.h"
#include "lsterr.h"
#include "serialis.h"

View File

@ -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;

View File

@ -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,38 +805,10 @@ 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> { \
class CLASSNAME##_LIST : public X_LIST<ELIST, ELIST_ITERATOR, CLASSNAME> { \
public: \
using X_LIST<CLASSNAME>::X_LIST; \
using X_LIST<ELIST, ELIST_ITERATOR, CLASSNAME>::X_LIST; \
}; \
class CLASSNAME##_IT : public X_ITER<ELIST_ITERATOR, CLASSNAME> { \
public: \

View File

@ -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;

View File

@ -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 { \
#define ELIST2IZEH(CLASSNAME) \
class CLASSNAME##_LIST : public X_LIST<ELIST2, ELIST2_ITERATOR, CLASSNAME> { \
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 { \
using X_LIST<ELIST2, ELIST2_ITERATOR, CLASSNAME>::X_LIST; \
}; \
class CLASSNAME##_IT : public X_ITER<ELIST2_ITERATOR, CLASSNAME> { \
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()); \
} \
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()); \
} \
CLASSNAME *extract() { \
return reinterpret_cast<CLASSNAME *>(ELIST2_ITERATOR::extract()); \
} \
\
private: \
CLASSNAME##_IT(); \
};
#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

View File

@ -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:

View File

@ -35,8 +35,6 @@
namespace tesseract {
ELIST2IZE(ColPartition)
//////////////// ColPartition Implementation ////////////////
// enum to refer to the entries in a neighbourhood of lines.

View File

@ -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.

View File

@ -46,7 +46,6 @@ public:
CLISTIZEH(Clst)
ELISTIZEH(Elst)
ELIST2IZEH(Elst2)
ELIST2IZE(Elst2)
TEST_F(ListTest, TestCLIST) {
Clst_CLIST list;