Fix comparison of QVariants that contain pointers to QObjects

Allow comparing variants of different types, if both types
are pointers to related objects.

Amends change 4a69cd7f72

Change-Id: Ib52b17781b0b7f60cfd5da42fce733faacfa0ae8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Lars Knoll 2020-08-19 10:21:30 +02:00
parent 4a1567ab12
commit f098aee532
1 changed files with 26 additions and 0 deletions

View File

@ -2076,6 +2076,8 @@ bool QVariant::convert(const int type, void *ptr) const
\li If one type is numeric and the other one a QString, Qt will try to
convert the QString to a matching numeric type and if successful compare
those.
\i If both variants contain pointers to QObject derived types, QVariant
will check whether the types are related and point to the same object.
\endlist
*/
@ -2097,6 +2099,8 @@ bool QVariant::convert(const int type, void *ptr) const
\li If one type is numeric and the other one a QString, Qt will try to
convert the QString to a matching numeric type and if successful compare
those.
\i If both variants contain pointers to QObject derived types, QVariant
will check whether the types are related and point to the same object.
\endlist
*/
@ -2251,6 +2255,23 @@ static bool numericEquals(const QVariant::Private *d1, const QVariant::Private *
return false;
}
#ifndef QT_BOOTSTRAPPED
static bool canConvertMetaObject(QMetaType fromType, QMetaType toType)
{
if ((fromType.flags() & QMetaType::PointerToQObject) && (toType.flags() & QMetaType::PointerToQObject)) {
return fromType.metaObject()->inherits(toType.metaObject()) ||
toType.metaObject()->inherits(fromType.metaObject());
}
return false;
}
static bool pointerEquals(const QVariant::Private *d1, const QVariant::Private *d2)
{
// simply check whether both types point to the same data
return d1->get<QObject *>() == d2->get<QObject *>();
}
#endif
/*!
\internal
*/
@ -2262,6 +2283,11 @@ bool QVariant::equals(const QVariant &v) const
// try numeric comparisons, with C++ type promotion rules (no conversion)
if (qIsNumericType(metatype.id()) && qIsNumericType(v.d.typeId()))
return numericEquals(&d, &v.d);
#ifndef QT_BOOTSTRAPPED
// if both types are related pointers to QObjects, check if they point to the same object
if (canConvertMetaObject(metatype, v.metaType()))
return pointerEquals(&d, &v.d);
#endif
return false;
}