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>
This commit is contained in:
Sean Harmer 2016-03-07 13:41:14 +00:00
parent 8eb721468e
commit aa21ac1043
3 changed files with 67 additions and 0 deletions

View File

@ -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

View File

@ -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;

View File

@ -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"