From 8549ca489f5f3146d59d3510dae9e47467a614c5f18b87620626cd71b41a8939 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Sat, 9 Aug 2025 06:31:08 -0400 Subject: [PATCH] Poor man's RTTI is mostly gone. I'm keeping the type-index to name mapping, for now. --- dw/alignedtablecell.cc | 4 +- dw/alignedtablecell.hh | 2 - dw/alignedtextblock.cc | 4 +- dw/alignedtextblock.hh | 2 - dw/image.cc | 4 +- dw/image.hh | 2 - dw/listitem.cc | 4 +- dw/listitem.hh | 2 - dw/oofawarewidget.cc | 4 +- dw/oofawarewidget.hh | 2 - dw/regardingborder.cc | 4 +- dw/regardingborder.hh | 2 - dw/ruler.cc | 4 +- dw/ruler.hh | 2 - dw/simpletablecell.cc | 4 +- dw/simpletablecell.hh | 2 - dw/table.cc | 3 +- dw/table.hh | 2 - dw/textblock.cc | 4 +- dw/textblock.hh | 2 - dw/ui.cc | 4 +- dw/ui.hh | 2 - dw/widget.cc | 3 +- dw/widget.hh | 2 - lout/identity.cc | 61 ++-------------------- lout/identity.hh | 112 ++++------------------------------------- 26 files changed, 27 insertions(+), 216 deletions(-) diff --git a/dw/alignedtablecell.cc b/dw/alignedtablecell.cc index 4e8f07f..7c10e17 100644 --- a/dw/alignedtablecell.cc +++ b/dw/alignedtablecell.cc @@ -27,13 +27,11 @@ using namespace lout; namespace dw { -std::intptr_t AlignedTableCell::CLASS_ID = -1; - AlignedTableCell::AlignedTableCell (AlignedTableCell *ref, bool limitTextWidth): AlignedTextblock (limitTextWidth) { DBG_OBJ_CREATE ("dw::AlignedTableCell"); - registerName ("dw::AlignedTableCell", typeid(*this), &CLASS_ID); + registerName ("dw::AlignedTableCell", typeid(*this)); /** \bug ignoreLine1OffsetSometimes does not work? */ //ignoreLine1OffsetSometimes = true; diff --git a/dw/alignedtablecell.hh b/dw/alignedtablecell.hh index ad235d9..63c1c48 100644 --- a/dw/alignedtablecell.hh +++ b/dw/alignedtablecell.hh @@ -33,8 +33,6 @@ protected: void setMaxValue (int maxValue, int value); public: - static std::intptr_t CLASS_ID; - AlignedTableCell(AlignedTableCell *ref, bool limitTextWidth); ~AlignedTableCell(); diff --git a/dw/alignedtextblock.cc b/dw/alignedtextblock.cc index 81fa51d..687858d 100644 --- a/dw/alignedtextblock.cc +++ b/dw/alignedtextblock.cc @@ -58,13 +58,11 @@ void AlignedTextblock::List::unref(int pos) delete this; } -std::intptr_t AlignedTextblock::CLASS_ID = -1; - AlignedTextblock::AlignedTextblock (bool limitTextWidth): Textblock (limitTextWidth) { DBG_OBJ_CREATE ("dw::AlignedTextblock"); - registerName ("dw::AlignedTextblock", typeid(*this), &CLASS_ID); + registerName ("dw::AlignedTextblock", typeid(*this)); } void AlignedTextblock::setRefTextblock (AlignedTextblock *ref) diff --git a/dw/alignedtextblock.hh b/dw/alignedtextblock.hh index a499ad9..1650b75 100644 --- a/dw/alignedtextblock.hh +++ b/dw/alignedtextblock.hh @@ -51,8 +51,6 @@ protected: void updateValue (); public: - static std::intptr_t CLASS_ID; - ~AlignedTextblock(); }; diff --git a/dw/image.cc b/dw/image.cc index df04615..7063490 100644 --- a/dw/image.cc +++ b/dw/image.cc @@ -131,12 +131,10 @@ int ImageMapsList::link (object::Object *key, int x, int y) // ---------------------------------------------------------------------- -std::intptr_t Image::CLASS_ID = -1; - Image::Image(const char *altText) { DBG_OBJ_CREATE ("dw::Image"); - registerName ("dw::Image", typeid(*this), &CLASS_ID); + registerName ("dw::Image", typeid(*this)); this->altText = altText ? dStrdup (altText) : NULL; altTextWidth = -1; // not yet calculated buffer = NULL; diff --git a/dw/image.hh b/dw/image.hh index b1d8e7d..fc66910 100644 --- a/dw/image.hh +++ b/dw/image.hh @@ -145,8 +145,6 @@ protected: //core::Iterator *iterator (Content::Type mask, bool atEnd); public: - static std::intptr_t CLASS_ID; - Image(const char *altText); ~Image(); diff --git a/dw/listitem.cc b/dw/listitem.cc index 23aa5e0..f31a948 100644 --- a/dw/listitem.cc +++ b/dw/listitem.cc @@ -25,13 +25,11 @@ namespace dw { -std::intptr_t ListItem::CLASS_ID = -1; - ListItem::ListItem (ListItem *ref, bool limitTextWidth): AlignedTextblock (limitTextWidth) { DBG_OBJ_CREATE ("dw::ListItem"); - registerName ("dw::ListItem", typeid(*this), &CLASS_ID); + registerName ("dw::ListItem", typeid(*this)); setRefTextblock (ref); } diff --git a/dw/listitem.hh b/dw/listitem.hh index e0b7780..a001e9c 100644 --- a/dw/listitem.hh +++ b/dw/listitem.hh @@ -13,8 +13,6 @@ protected: void setMaxValue (int maxValue, int value); public: - static std::intptr_t CLASS_ID; - ListItem(ListItem *ref, bool limitTextWidth); ~ListItem(); diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc index 2cf4c15..845e88c 100644 --- a/dw/oofawarewidget.cc +++ b/dw/oofawarewidget.cc @@ -38,12 +38,10 @@ const char *OOFAwareWidget::OOFM_NAME[NUM_OOFM] = { "FLOATS", "ABSOLUTE", "RELATIVE", "FIXED" }; -std::intptr_t OOFAwareWidget::CLASS_ID = -1; - OOFAwareWidget::OOFAwareWidget () { DBG_OBJ_CREATE ("dw::oof::OOFAwareWidget"); - registerName ("dw::oof::OOFAwareWidget", typeid(*this), &CLASS_ID); + registerName ("dw::oof::OOFAwareWidget", typeid(*this)); for (int i = 0; i < NUM_OOFM; i++) { oofContainer[i] = NULL; diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh index 76f4412..d8ee74d 100644 --- a/dw/oofawarewidget.hh +++ b/dw/oofawarewidget.hh @@ -195,8 +195,6 @@ public: SL_START, SL_BACKGROUND, SL_SC_BOTTOM, SL_IN_FLOW, SL_OOF_REF, SL_OOF_CONT, SL_SC_TOP, SL_END }; - static std::intptr_t CLASS_ID; - OOFAwareWidget (); ~OOFAwareWidget (); diff --git a/dw/regardingborder.cc b/dw/regardingborder.cc index c5ba83c..4159a5c 100644 --- a/dw/regardingborder.cc +++ b/dw/regardingborder.cc @@ -23,12 +23,10 @@ namespace dw { -std::intptr_t RegardingBorder::CLASS_ID = -1; - RegardingBorder::RegardingBorder () { DBG_OBJ_CREATE ("dw::RegardingBorder"); - registerName ("dw::RegardingBorder", typeid(*this), &CLASS_ID); + registerName ("dw::RegardingBorder", typeid(*this)); } RegardingBorder::~RegardingBorder () diff --git a/dw/regardingborder.hh b/dw/regardingborder.hh index cfb2aad..430dbc1 100644 --- a/dw/regardingborder.hh +++ b/dw/regardingborder.hh @@ -13,8 +13,6 @@ namespace dw { class RegardingBorder: public oof::OOFAwareWidget { public: - static std::intptr_t CLASS_ID; - RegardingBorder (); ~RegardingBorder (); }; diff --git a/dw/ruler.cc b/dw/ruler.cc index ae7cc06..d1da030 100644 --- a/dw/ruler.cc +++ b/dw/ruler.cc @@ -26,12 +26,10 @@ namespace dw { -std::intptr_t Ruler::CLASS_ID = -1; - Ruler::Ruler () { DBG_OBJ_CREATE ("dw::Ruler"); - registerName ("dw::Ruler", typeid(*this), &CLASS_ID); + registerName ("dw::Ruler", typeid(*this)); } Ruler::~Ruler () diff --git a/dw/ruler.hh b/dw/ruler.hh index b6c7cc9..5dcc73a 100644 --- a/dw/ruler.hh +++ b/dw/ruler.hh @@ -30,8 +30,6 @@ protected: core::GettingWidgetAtPointContext *context); public: - static std::intptr_t CLASS_ID; - Ruler (); ~Ruler (); diff --git a/dw/simpletablecell.cc b/dw/simpletablecell.cc index 4beb111..717ad2a 100644 --- a/dw/simpletablecell.cc +++ b/dw/simpletablecell.cc @@ -27,13 +27,11 @@ using namespace lout; namespace dw { -std::intptr_t SimpleTableCell::CLASS_ID = -1; - SimpleTableCell::SimpleTableCell (bool limitTextWidth): Textblock (limitTextWidth) { DBG_OBJ_CREATE ("dw::SimpleTableCell"); - registerName ("dw::SimpleTableCell", typeid(*this), &CLASS_ID); + registerName ("dw::SimpleTableCell", typeid(*this)); } SimpleTableCell::~SimpleTableCell() diff --git a/dw/simpletablecell.hh b/dw/simpletablecell.hh index ed3525c..581a78b 100644 --- a/dw/simpletablecell.hh +++ b/dw/simpletablecell.hh @@ -24,8 +24,6 @@ protected: bool adjustExtraSpaceWhenCorrectingRequisitionByOOF (); public: - static std::intptr_t CLASS_ID; - SimpleTableCell (bool limitTextWidth); ~SimpleTableCell (); diff --git a/dw/table.cc b/dw/table.cc index 26aa904..fe43a2f 100644 --- a/dw/table.cc +++ b/dw/table.cc @@ -29,12 +29,11 @@ using namespace lout; namespace dw { bool Table::adjustTableMinWidth = true; -std::intptr_t Table::CLASS_ID = -1; Table::Table(bool limitTextWidth) { DBG_OBJ_CREATE ("dw::Table"); - registerName ("dw::Table", typeid(*this), &CLASS_ID); + registerName ("dw::Table", typeid(*this)); setButtonSensitive(false); this->limitTextWidth = limitTextWidth; diff --git a/dw/table.hh b/dw/table.hh index 866ff85..b98ee78 100644 --- a/dw/table.hh +++ b/dw/table.hh @@ -492,8 +492,6 @@ protected: void removeChild (Widget *child); public: - static std::intptr_t CLASS_ID; - inline static void setAdjustTableMinWidth (bool adjustTableMinWidth) { Table::adjustTableMinWidth = adjustTableMinWidth; } diff --git a/dw/textblock.cc b/dw/textblock.cc index b66b5c7..5227b7c 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -43,8 +43,6 @@ using namespace lout::unicode; namespace dw { -std::intptr_t Textblock::CLASS_ID = -1; - Textblock::WordImgRenderer::WordImgRenderer (Textblock *textblock, int wordNo) { @@ -206,7 +204,7 @@ void Textblock::setStretchabilityFactor (int stretchabilityFactor) Textblock::Textblock (bool limitTextWidth, bool treatAsInline) { DBG_OBJ_CREATE ("dw::Textblock"); - registerName ("dw::Textblock", typeid(*this), &CLASS_ID); + registerName ("dw::Textblock", typeid(*this)); setButtonSensitive(true); hasListitemValue = false; diff --git a/dw/textblock.hh b/dw/textblock.hh index 30d18d8..c56a0c4 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -864,8 +864,6 @@ protected: int getGeneratorRest (int oofmIndex); public: - static std::intptr_t CLASS_ID; - static void setPenaltyHyphen (int penaltyHyphen); static void setPenaltyHyphen2 (int penaltyHyphen2); static void setPenaltyEmDashLeft (int penaltyLeftEmDash); diff --git a/dw/ui.cc b/dw/ui.cc index 9fd6add..cb1b0f3 100644 --- a/dw/ui.cc +++ b/dw/ui.cc @@ -32,12 +32,10 @@ namespace ui { using namespace lout; using namespace lout::object; -std::intptr_t Embed::CLASS_ID = -1; - Embed::Embed(Resource *resource) { DBG_OBJ_CREATE ("dw::core::ui::Embed"); - registerName ("dw::core::ui::Embed", typeid(*this), &CLASS_ID); + registerName ("dw::core::ui::Embed", typeid(*this)); this->resource = resource; resource->setEmbed (this); DBG_OBJ_ASSOC_CHILD (resource); diff --git a/dw/ui.hh b/dw/ui.hh index 46bde3b..79e7de0 100644 --- a/dw/ui.hh +++ b/dw/ui.hh @@ -251,8 +251,6 @@ protected: bool buttonPressImpl (core::EventButton *event); public: - static std::intptr_t CLASS_ID; - Embed(Resource *resource); ~Embed(); diff --git a/dw/widget.cc b/dw/widget.cc index 27e53d6..db1f4d4 100644 --- a/dw/widget.cc +++ b/dw/widget.cc @@ -73,12 +73,11 @@ void Widget::WidgetImgRenderer::draw (int x, int y, int width, int height) // ---------------------------------------------------------------------- bool Widget::adjustMinWidth = true; -std::intptr_t Widget::CLASS_ID = -1; Widget::Widget () { DBG_OBJ_CREATE ("dw::core::Widget"); - registerName ("dw::core::Widget", typeid(*this), &CLASS_ID); + registerName ("dw::core::Widget", typeid(*this)); DBG_OBJ_ASSOC_CHILD (&requisitionParams); DBG_OBJ_ASSOC_CHILD (&extremesParams); diff --git a/dw/widget.hh b/dw/widget.hh index 9dbd9cd..d05d2de 100644 --- a/dw/widget.hh +++ b/dw/widget.hh @@ -458,8 +458,6 @@ private: public: - static std::intptr_t CLASS_ID; - inline static void setAdjustMinWidth (bool adjustMinWidth) { Widget::adjustMinWidth = adjustMinWidth; } diff --git a/lout/identity.cc b/lout/identity.cc index 22af639..a69e517 100644 --- a/lout/identity.cc +++ b/lout/identity.cc @@ -24,47 +24,7 @@ namespace lout { namespace identity { -// ------------------------ -// IdentifiableObject -// ------------------------ - -using namespace object; -using namespace container::typed; - -IdentifiableObject::Class::Class (IdentifiableObject::Class *parent, const std::type_index id, - const char *className) - : id( (std::intptr_t) id.name() ) -{ - this->parent = parent; - this->className = className; -} - -void IdentifiableObject::Class::intoStringBuffer(misc::StringBuffer *sb) -{ - sb->append ("append (className); - sb->append (" ("); - sb->appendInt (id); - sb->append (")"); - - if (parent) { - sb->append (", parent: "); - parent->intoStringBuffer (sb); - } - - sb->append (">"); -} - -std::map< std::string, std::unique_ptr< IdentifiableObject::Class > > IdentifiableObject::classesByName; - -std::map< std::intptr_t, IdentifiableObject::Class * > IdentifiableObject::classesById; - -IdentifiableObject::Class *IdentifiableObject::currentlyConstructedClass; - -IdentifiableObject::IdentifiableObject () -{ - currentlyConstructedClass = NULL; -} +std::map< std::type_index, std::string > IdentifiableObject::classNames; void IdentifiableObject::intoStringBuffer(misc::StringBuffer *sb) { @@ -76,23 +36,12 @@ void IdentifiableObject::intoStringBuffer(misc::StringBuffer *sb) } /** - * \brief This method must be called in the constructor for the sub class. - * See class comment for details. + * Register a name for a class. */ -void IdentifiableObject::registerName (const char *className, const std::type_index index, std::intptr_t *classId) +void +IdentifiableObject::registerName( const char *const className, const std::type_index index ) { - if (not classesByName.contains( className )) { - classesByName.emplace( className, - std::make_unique< Class >( currentlyConstructedClass, index, className ) ); - auto *const klass= classesByName.at( className ).get(); - classesById[ klass->id ]= klass; - *classId = klass->id; - } - Class *const klass = classesByName.at( className ).get(); - - this->classId = klass->id; - *classId = klass->id; - currentlyConstructedClass = klass; + classNames.insert( { index, className } ); } } // namespace identity diff --git a/lout/identity.hh b/lout/identity.hh index 6230ef1..b7a1bf0 100644 --- a/lout/identity.hh +++ b/lout/identity.hh @@ -15,127 +15,35 @@ namespace lout { /** - * \brief Some stuff to identify classes of objects at run-time. + * \brief This was a poor man's RTTI implementation. */ namespace identity { /** - * \brief Instances of classes, which are sub classes of this class, may - * be identified at run-time. + * Hooks for class name inspection. * - *

Testing the class

+ * It began life as an RTTI clone. It did not support multiple inheritance. * - * Since e.g. dw::Textblock is a sub class of IdentifiableObject, and - * implemented in the correct way (as described below), for any given - * IdentifiableObject the following test can be done: - * - * \code - * identity::IdentifiableObject *o; - * // ... - * bool isATextblock = o->instanceOf(dw::Textblock::CLASS_ID); - * \endcode - * - * \em isATextblock is true, when \em o is an instance of dw::Textblock, - * or of a sub class of dw::Textblock. Otherwise, \em isATextblock is false. - * - * It is also possible to get the class identifier of an - * identity::IdentifiableObject, e.g. - * - * \code - * bool isOnlyATextblock = o->getClassId() == dw::Textblock::CLASS_ID; - * \endcode - * - * would result in true, if o is an instance of dw::Textblock, but not an - * instance of a sub class of dw::Textblock. - * - *

Defining Sub Classes

- * - * Each direct or indirect sub class of IdentifiableObject must - * - * - * - * After this, class\::CLASS_ID refers to a number, which denotes the - * class. (If this is still -1, since the class has not yet been instantiated, - * any test will fail, which is correct.) - * - *

Notes on implementation

- * - * If there are some classes like this: - * - * \dot - * digraph G { - * node [shape=record, fontname=Helvetica, fontsize=10]; - * edge [arrowhead="none", arrowtail="empty", labelfontname=Helvetica, - * labelfontsize=10, color="#404040", labelfontcolor="#000080"]; - * fontname=Helvetica; fontsize=10; - * IdentifiableObject [color="#a0a0a0"]; - * A; - * B [color="#a0a0a0"]; - * C; - * IdentifiableObject -> A; - * IdentifiableObject -> B; - * B -> C; - * } - * \enddot - * - *
[\ref uml-legend "legend"]
- * - * and first, an instance of A, and then an instance of C is created, there - * will be the following calls of functions and constructors: - * - *
    - *
  1. %IdentifiableObject (); - *
  2. %registerName ("A", &A::CLASS_ID); - *
  3. %IdentifiableObject (); - *
  4. %registerName ("B", &B::CLASS_ID); - *
  5. %registerName ("C", &C::CLASS_ID); - *
- * - * From this, the class hierarchy above can easily constructed, and stored - * in identity::IdentifiableObject::classesByName and - * in identity::IdentifiableObject::classesById. See the code for details. - * - * N.b. Multiple inheritance is not supported, the construction of the - * tree would become confused. + * It appeared to be a model of Java's `Object` system. It's mostly been migrated + * to use C++ RTTI and most use cases should be avoiding the `lout::contaner` stuff. */ class IdentifiableObject: public object::Object { private: - class Class final: public object::Object - { - public: - Class *parent; - std::intptr_t id; - const char *className; - - Class (Class *parent, std::type_index id, const char *className); - - void intoStringBuffer(misc::StringBuffer *sb); - }; - - static std::map< std::string, std::unique_ptr< Class > > classesByName; - static std::map< std::intptr_t, Class * > classesById; - static Class *currentlyConstructedClass; - - std::intptr_t classId; + // TODO: Use the Alepha facility for this, eventually... + static std::map< std::type_index, std::string > classNames; protected: - void registerName (const char *className, std::type_index index, std::intptr_t *classId); + void registerName (const char *className, std::type_index index); public: - IdentifiableObject (); - - void intoStringBuffer(misc::StringBuffer *sb); + void intoStringBuffer(misc::StringBuffer *sb) override; /** * \brief Return the name, under which the class of this object was * registered. */ - const char *getClassName() { return classesById.at( classId )->className; } + const char *getClassName() { return classNames.at( typeid( *this ) ).c_str(); } }; } // namespace identity