[QoI] Support polymorphism when extracting log category from QObject

This commit is contained in:
Mat Sutcliffe
2021-07-22 19:17:56 +01:00
parent dd9f9bc46f
commit 0c5d684957
2 changed files with 13 additions and 7 deletions

View File

@@ -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());
}

View File

@@ -66,7 +66,7 @@ namespace BlackMisc
* It is legal to pass static_cast<T>(nullptr), but in member functions passing the <tt>this</tt> pointer is easier.
*/
template <typename T, typename = std::enable_if_t<std::is_class_v<T>>>
CLogCategoryList(const T *pointer) : CLogCategoryList(fromClass<T>()) { 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 <typename T>
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<T>::value) { list.push_back(fromQStringList(T::getLogCategories())); }
if constexpr (QMetaTypeId<T>::Defined) { list.push_back(QMetaType::typeName(qMetaTypeId<T>())); }
if constexpr (std::is_base_of_v<QObject, T>) { list.appendCategoriesFromMetaObject(T::staticMetaObject); }
if (list.isEmpty()) { list.push_back(CLogCategories::uncategorized()); }
return list;
}();
auto list = staticList;
if constexpr (std::is_base_of_v<QObject, T>)
{
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);
};
}