From 0c5d684957073bc3368f44e2e382f246f662cda8 Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Thu, 22 Jul 2021 19:17:56 +0100 Subject: [PATCH] [QoI] Support polymorphism when extracting log category from QObject --- src/blackmisc/logcategorylist.cpp | 4 ++-- src/blackmisc/logcategorylist.h | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/blackmisc/logcategorylist.cpp b/src/blackmisc/logcategorylist.cpp index f10f380b9..0681f4a8d 100644 --- a/src/blackmisc/logcategorylist.cpp +++ b/src/blackmisc/logcategorylist.cpp @@ -20,9 +20,9 @@ struct QMetaObject; namespace BlackMisc { - void CLogCategoryList::appendCategoriesFromMetaObject(const QMetaObject &metaObject) + void CLogCategoryList::appendCategoriesFromMetaObject(const QMetaObject &metaObject, const QMetaObject &super) { - for (auto *meta = &metaObject; meta; meta = meta->superClass()) + for (auto *meta = &metaObject; meta != &super; meta = meta->superClass()) { push_back(meta->className()); } diff --git a/src/blackmisc/logcategorylist.h b/src/blackmisc/logcategorylist.h index 62e97c8a7..90065815c 100644 --- a/src/blackmisc/logcategorylist.h +++ b/src/blackmisc/logcategorylist.h @@ -66,7 +66,7 @@ namespace BlackMisc * It is legal to pass static_cast(nullptr), but in member functions passing the this pointer is easier. */ template >> - CLogCategoryList(const T *pointer) : CLogCategoryList(fromClass()) { Q_UNUSED(pointer); } + CLogCategoryList(const T *pointer) : CLogCategoryList(fromClass(pointer)) {} //! Return a copy with another category appended. CLogCategoryList with(const CLogCategory &other) const { auto copy = *this; copy.push_back(other); return copy; } @@ -103,22 +103,28 @@ namespace BlackMisc private: template - static const CLogCategoryList &fromClass() + static CLogCategoryList fromClass(const T *ptr) { static_assert(sizeof(T) > 0, "T must be a complete type, not forward declared"); - static const auto list = [] + static const auto staticList = [] { CLogCategoryList list; if constexpr (THasGetLogCategories::value) { list.push_back(fromQStringList(T::getLogCategories())); } if constexpr (QMetaTypeId::Defined) { list.push_back(QMetaType::typeName(qMetaTypeId())); } if constexpr (std::is_base_of_v) { list.appendCategoriesFromMetaObject(T::staticMetaObject); } - if (list.isEmpty()) { list.push_back(CLogCategories::uncategorized()); } return list; }(); + auto list = staticList; + if constexpr (std::is_base_of_v) + { + if (ptr) { list.appendCategoriesFromMetaObject(*ptr->metaObject(), T::staticMetaObject); } + } + else { Q_UNUSED(ptr); } + if (list.isEmpty()) { return { CLogCategories::uncategorized() }; } return list; } - void appendCategoriesFromMetaObject(const QMetaObject &); + void appendCategoriesFromMetaObject(const QMetaObject &, const QMetaObject &super = QObject::staticMetaObject); }; }