summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-06-08 12:55:43 +0200
committerLars Knoll <lars.knoll@qt.io>2020-08-13 08:48:03 +0200
commit50c96c17b6c87d48418336dc124a6de3f1f1958b (patch)
tree962402f22076847ba61a1877a269bac8460beb3b /src
parent2002158a13517411ba797788331e8865cca514e5 (diff)
Use the new support for comparisons in QMetaType for QVariant
Remove the compare method in the QVariant::Handler struct. Rely on the generic support provided by QMetaType instead. [ChangeLog][Important Behavior Changes][QVariant] QVariant will now use builtin support in QMetaType to compare its content. This implies a behavioral change for some graphical types like QPixmap, QImage and QIcon that will never compare equal in Qt 6 (as they do not have a comparison operator). Change-Id: I30a6e7116c89124d11ed9052537cecc23f78116e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qvariant.cpp51
-rw-r--r--src/corelib/kernel/qvariant.h10
-rw-r--r--src/corelib/kernel/qvariant_p.h43
-rw-r--r--src/gui/kernel/qguivariant.cpp43
-rw-r--r--src/widgets/kernel/qwidgetsvariant.cpp13
5 files changed, 13 insertions, 147 deletions
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index f8859ddedc..63466f9de8 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -125,18 +125,6 @@ static bool isNull(const QVariant::Private *d)
/*!
\internal
-
- Compares \a a to \a b. The caller guarantees that \a a and \a b
- are of the same type.
- */
-static bool compare(const QVariant::Private *a, const QVariant::Private *b)
-{
- QVariantComparator<CoreTypesFilter> comparator(a, b);
- return QMetaTypeSwitcher::switcher<bool>(comparator, a->type().id());
-}
-
-/*!
- \internal
*/
static qlonglong qMetaTypeNumber(const QVariant::Private *d)
{
@@ -1390,7 +1378,6 @@ static void streamDebug(QDebug dbg, const QVariant &v)
const QVariant::Handler qt_kernel_variant_handler = {
isNull,
- compare,
convert,
#if !defined(QT_NO_DEBUG_STREAM)
streamDebug
@@ -1400,14 +1387,12 @@ const QVariant::Handler qt_kernel_variant_handler = {
};
static bool dummyIsNull(const QVariant::Private *d) { Q_ASSERT_X(false, "QVariant::isNull", "Trying to call isNull on an unknown type"); return d->is_null; }
-static bool dummyCompare(const QVariant::Private *, const QVariant::Private *) { Q_ASSERT_X(false, "QVariant", "Trying to compare an unknown types"); return false; }
static bool dummyConvert(const QVariant::Private *, int, void *, bool *) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); return false; }
#if !defined(QT_NO_DEBUG_STREAM)
static void dummyStreamDebug(QDebug, const QVariant &) { Q_ASSERT_X(false, "QVariant", "Trying to convert an unknown type"); }
#endif
const QVariant::Handler qt_dummy_variant_handler = {
dummyIsNull,
- dummyCompare,
dummyConvert,
#if !defined(QT_NO_DEBUG_STREAM)
dummyStreamDebug
@@ -1468,17 +1453,6 @@ static bool customIsNull(const QVariant::Private *d)
return false;
}
-static bool customCompare(const QVariant::Private *a, const QVariant::Private *b)
-{
- const void *a_ptr = a->is_shared ? a->data.shared->ptr : &(a->data);
- const void *b_ptr = b->is_shared ? b->data.shared->ptr : &(b->data);
-
- if (a->is_null && b->is_null)
- return true;
-
- return !memcmp(a_ptr, b_ptr, a->type().sizeOf());
-}
-
static bool customConvert(const QVariant::Private *d, int t, void *result, bool *ok)
{
if (d->type().id() >= QMetaType::User || t >= QMetaType::User) {
@@ -1506,7 +1480,6 @@ static void customStreamDebug(QDebug dbg, const QVariant &variant) {
const QVariant::Handler qt_custom_variant_handler = {
customIsNull,
- customCompare,
customConvert,
#if !defined(QT_NO_DEBUG_STREAM)
customStreamDebug
@@ -3909,23 +3882,13 @@ static int numericCompare(const QVariant::Private *d1, const QVariant::Private *
/*!
\internal
*/
-bool QVariant::cmp(const QVariant &v) const
-{
- auto cmp_helper = [](const QVariant::Private &d1, const QVariant::Private &d2) {
- Q_ASSERT(d1.type() == d2.type());
- auto metatype = d1.type();
- if (metatype.id() >= QMetaType::User)
- return metatype.equals(QT_PREPEND_NAMESPACE(constData(d1)), QT_PREPEND_NAMESPACE(constData(d2)));
- return handlerManager[d1.type().id()]->compare(&d1, &d2);
- };
-
+bool QVariant::equals(const QVariant &v) const
+{
+ auto metatype = d.type();
// try numerics first, with C++ type promotion rules (no conversion)
- if (qIsNumericType(d.type().id()) && qIsNumericType(v.d.type().id()))
+ if (qIsNumericType(metatype.id()) && qIsNumericType(v.d.type().id()))
return numericCompare(&d, &v.d) == 0;
- if (d.type() == v.d.type())
- return cmp_helper(d, v.d);
-
QVariant v1 = *this;
QVariant v2 = v;
if (v2.canConvert(v1.d.type().id())) {
@@ -3937,7 +3900,11 @@ bool QVariant::cmp(const QVariant &v) const
if (!v2.convert(v1.d.type().id()))
return false;
}
- return cmp_helper(v1.d, v2.d);
+ metatype = v1.metaType();
+ // For historical reasons: QVariant() == QVariant()
+ if (!metatype.isValid())
+ return true;
+ return metatype.equals(QT_PREPEND_NAMESPACE(constData(v1.d)), QT_PREPEND_NAMESPACE(constData(v2.d)));
}
/*!
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index e7b64c2aed..498ba57399 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -470,20 +470,18 @@ class Q_CORE_EXPORT QVariant
};
public:
typedef bool (*f_null)(const Private *);
- typedef bool (*f_compare)(const Private *, const Private *);
typedef bool (*f_convert)(const QVariant::Private *d, int t, void *, bool *);
typedef void (*f_debugStream)(QDebug, const QVariant &);
struct Handler {
f_null isNull;
- f_compare compare;
f_convert convert;
f_debugStream debugStream;
};
inline bool operator==(const QVariant &v) const
- { return cmp(v); }
+ { return equals(v); }
inline bool operator!=(const QVariant &v) const
- { return !cmp(v); }
+ { return !equals(v); }
protected:
friend inline bool operator==(const QVariant &, const QVariantComparisonHelper &);
@@ -501,7 +499,7 @@ public:
#endif
Private d;
void create(int type, const void *copy);
- bool cmp(const QVariant &other) const;
+ bool equals(const QVariant &other) const;
bool convert(const int t, void *ptr) const; // ### Qt6: drop const
private:
@@ -584,7 +582,7 @@ private:
inline bool operator==(const QVariant &v1, const QVariantComparisonHelper &v2)
{
- return v1.cmp(*v2.v);
+ return v1.equals(*v2.v);
}
inline bool operator!=(const QVariant &v1, const QVariantComparisonHelper &v2)
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index 8739cb5173..2cec8ff65b 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -212,49 +212,6 @@ public:
}
};
-template<class Filter>
-class QVariantComparator {
- template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
- struct FilteredComparator {
- static bool compare(const QVariant::Private *a, const QVariant::Private *b)
- {
- return *v_cast<T>(a) == *v_cast<T>(b);
- }
- };
- template<typename T>
- struct FilteredComparator<T, /* IsAcceptedType = */ false> {
- static bool compare(const QVariant::Private *, const QVariant::Private *)
- {
- // It is not possible to construct a QVariant containing not fully defined type
- Q_ASSERT(false);
- return false;
- }
- };
-public:
- QVariantComparator(const QVariant::Private *a, const QVariant::Private *b)
- : m_a(a), m_b(b)
- {
- Q_ASSERT(a->type() == b->type());
- }
-
- template<typename T>
- bool delegate(const T*)
- {
- return FilteredComparator<T>::compare(m_a, m_b);
- }
-
- bool delegate(const void*) { Q_ASSERT(false); return true; }
- bool delegate(const QMetaTypeSwitcher::UnknownType*)
- {
- return true; // for historical reason invalid variant == invalid variant
- }
- bool delegate(const QMetaTypeSwitcher::NotBuiltinType*) { return false; }
-protected:
- const QVariant::Private *m_a;
- const QVariant::Private *m_b;
-};
-
-
Q_CORE_EXPORT const QVariant::Handler *qcoreVariantHandler();
template<class Filter>
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index 565e91d662..efd98f691d 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -121,48 +121,6 @@ static bool isNull(const QVariant::Private *d)
return QMetaTypeSwitcher::switcher<bool>(isNull, d->type().id(), nullptr);
}
-// This class is a hack that customizes access to QPixmap, QBitmap, QCursor and QIcon
-template<class Filter>
-class QGuiVariantComparator : public QVariantComparator<Filter> {
- typedef QVariantComparator<Filter> Base;
-public:
- QGuiVariantComparator(const QVariant::Private *a, const QVariant::Private *b)
- : QVariantComparator<Filter>(a, b)
- {}
- template<typename T>
- bool delegate(const T *p)
- {
- return Base::delegate(p);
- }
- bool delegate(const QPixmap*)
- {
- return v_cast<QPixmap>(Base::m_a)->cacheKey() == v_cast<QPixmap>(Base::m_b)->cacheKey();
- }
- bool delegate(const QBitmap*)
- {
- return v_cast<QBitmap>(Base::m_a)->cacheKey() == v_cast<QBitmap>(Base::m_b)->cacheKey();
- }
-#ifndef QT_NO_CURSOR
- bool delegate(const QCursor*)
- {
- return v_cast<QCursor>(Base::m_a)->shape() == v_cast<QCursor>(Base::m_b)->shape();
- }
-#endif
-#ifndef QT_NO_ICON
- bool delegate(const QIcon *)
- {
- return v_cast<QIcon>(Base::m_a)->cacheKey() == v_cast<QIcon>(Base::m_b)->cacheKey();
- }
-#endif
- bool delegate(const void *p) { return Base::delegate(p); }
-};
-
-static bool compare(const QVariant::Private *a, const QVariant::Private *b)
-{
- QGuiVariantComparator<GuiTypesFilter> comparator(a, b);
- return QMetaTypeSwitcher::switcher<bool>(comparator, a->type().id(), nullptr);
-}
-
static bool convert(const QVariant::Private *d, int t,
void *result, bool *ok)
{
@@ -306,7 +264,6 @@ static void streamDebug(QDebug dbg, const QVariant &v)
const QVariant::Handler qt_gui_variant_handler = {
isNull,
- compare,
convert,
#if !defined(QT_NO_DEBUG_STREAM)
streamDebug
diff --git a/src/widgets/kernel/qwidgetsvariant.cpp b/src/widgets/kernel/qwidgetsvariant.cpp
index 15a48bf683..31bb92bb2e 100644
--- a/src/widgets/kernel/qwidgetsvariant.cpp
+++ b/src/widgets/kernel/qwidgetsvariant.cpp
@@ -54,18 +54,6 @@ static bool isNull(const QVariant::Private *)
return false;
}
-static bool compare(const QVariant::Private *a, const QVariant::Private *b)
-{
- Q_ASSERT(a->type() == b->type());
- switch (a->type().id()) {
- case QMetaType::QSizePolicy:
- return *v_cast<QSizePolicy>(a) == *v_cast<QSizePolicy>(b);
- default:
- Q_ASSERT(false);
- }
- return false;
-}
-
static bool convert(const QVariant::Private *d, int type, void *result, bool *ok)
{
Q_UNUSED(d);
@@ -92,7 +80,6 @@ static void streamDebug(QDebug dbg, const QVariant &v)
static const QVariant::Handler widgets_handler = {
isNull,
- compare,
convert,
#if !defined(QT_NO_DEBUG_STREAM)
streamDebug