summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2016-03-07 13:41:14 +0000
committerSean Harmer <sean.harmer@kdab.com>2016-03-15 16:36:22 +0000
commitaa21ac1043d58b9749077a237aab51e14f06d16e (patch)
treedbb57115e6edb595cf41458b6c70ad066008a48d
parent8eb721468e9462605368d0469d404c0ee6fab854 (diff)
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) <ogoffart@woboq.com> Reviewed-by: Milian Wolff <milian.wolff@kdab.com> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
-rw-r--r--src/corelib/kernel/qmetaobject.cpp18
-rw-r--r--src/corelib/kernel/qobjectdefs.h1
-rw-r--r--tests/auto/corelib/kernel/qmetaobject/tst_qmetaobject.cpp48
3 files changed, 67 insertions, 0 deletions
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 1c426225a5..8024c97373 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 951668fe55..3d47bae4a0 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 2f954e16cf..fd32dc1ef8 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<const QMetaObject *>("derivedMetaObject");
+ QTest::addColumn<const QMetaObject *>("baseMetaObject");
+ QTest::addColumn<bool>("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"