From aa21ac1043d58b9749077a237aab51e14f06d16e Mon Sep 17 00:00:00 2001 From: Sean Harmer Date: Mon, 7 Mar 2016 13:41:14 +0000 Subject: [PATCH] Add a function to QMetaObject to check for inheritance This is analogous to QObject::inherits() but only requires the metaobjects rather than pointers to a QObject instances. This is needed for type checking on the backend of Qt 3D where we do not have access to QObject pointers. Change-Id: I14d26c4cbb5cc3fbecb57725f2c14ee0ffda4a11 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Milian Wolff Reviewed-by: Lars Knoll --- src/corelib/kernel/qmetaobject.cpp | 18 +++++++ src/corelib/kernel/qobjectdefs.h | 1 + .../kernel/qmetaobject/tst_qmetaobject.cpp | 48 +++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 1c426225a5b..8024c973732 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -325,6 +325,24 @@ const char *QMetaObject::className() const \sa className() */ +/* + Returns \c true if the class described by this QMetaObject inherits + the type described by \a metaObject; otherwise returns false. + + A type is considered to inherit itself. + + \since 5.7 +*/ +bool QMetaObject::inherits(const QMetaObject *metaObject) const Q_DECL_NOEXCEPT +{ + const QMetaObject *m = this; + do { + if (metaObject == m) + return true; + } while ((m = m->d.superdata)); + return false; +} + /*! \internal diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 951668fe552..3d47bae4a08 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -327,6 +327,7 @@ struct Q_CORE_EXPORT QMetaObject const char *className() const; const QMetaObject *superClass() const; + bool inherits(const QMetaObject *metaObject) const Q_DECL_NOEXCEPT; QObject *cast(QObject *obj) const; const QObject *cast(const QObject *obj) const; diff --git a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp index 2f954e16cf3..fd32dc1ef84 100644 --- a/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp @@ -131,6 +131,22 @@ namespace MyNamespace { MyEnum m_enum; MyFlags m_flags; }; + + // Test inherits + class MyClassSubclass : public MyClass + { + Q_OBJECT + }; + + class MyClassSubclass2 : public MyClass2 + { + Q_OBJECT + }; + + class MyClass2Subclass : public MyClass + { + Q_OBJECT + }; } @@ -222,6 +238,9 @@ private slots: void signalIndex(); void enumDebugStream(); + void inherits_data(); + void inherits(); + signals: void value6Changed(); void value7Changed(const QString &); @@ -1425,5 +1444,34 @@ void tst_QMetaObject::enumDebugStream() qDebug() << f1 << f2; } +void tst_QMetaObject::inherits_data() +{ + QTest::addColumn("derivedMetaObject"); + QTest::addColumn("baseMetaObject"); + QTest::addColumn("inheritsResult"); + + QTest::newRow("MyClass inherits QObject") + << &MyNamespace::MyClass::staticMetaObject << &QObject::staticMetaObject << true; + QTest::newRow("QObject inherits MyClass") + << &QObject::staticMetaObject << &MyNamespace::MyClass::staticMetaObject << false; + QTest::newRow("MyClass inherits MyClass") + << &MyNamespace::MyClass::staticMetaObject << &MyNamespace::MyClass::staticMetaObject << true; + QTest::newRow("MyClassSubclass inherits QObject") + << &MyNamespace::MyClassSubclass::staticMetaObject << &QObject::staticMetaObject << true; + QTest::newRow("MyClassSubclass2 inherits QObject") + << &MyNamespace::MyClassSubclass2::staticMetaObject << &QObject::staticMetaObject << true; + QTest::newRow("MyClassSubclass2 inherits MyClass2") + << &MyNamespace::MyClassSubclass2::staticMetaObject << &MyNamespace::MyClass2Subclass::staticMetaObject << false; +} + +void tst_QMetaObject::inherits() +{ + QFETCH(const QMetaObject *, derivedMetaObject); + QFETCH(const QMetaObject *, baseMetaObject); + QFETCH(bool, inheritsResult); + + QCOMPARE(derivedMetaObject->inherits(baseMetaObject), inheritsResult); +} + QTEST_MAIN(tst_QMetaObject) #include "tst_qmetaobject.moc"