From 5d8b586e73e37070b0303bee24372550854637eb Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 3 Dec 2020 09:14:27 +0100 Subject: Add a qHashEquals() method and use it to compare keys in QHash In some cases, the default equality operator for a class is not suitable for using in hashing (for example because it uses fuzzy comparisons). Add a qHashEquals() method that by default uses the equality operator, but allows to tailor the operations that should be used when using the class as a key in QHash. Pick-to: 6.0 dev Task-number: QTBUG-88966 Change-Id: I346cf0e6e923277a8b42a79e50342a1c2511fd80 Reviewed-by: Volker Hilsheimer --- src/corelib/tools/qhash.cpp | 15 +++++++++++++++ src/corelib/tools/qhash.h | 2 +- src/corelib/tools/qhashfunctions.h | 6 ++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 112a492526..1087f21564 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -1074,6 +1074,21 @@ size_t qHash(long double key, size_t seed) noexcept Returns the hash value for the \a key, using \a seed to seed the calculation. */ +/*! \fn template bool qHashEquals(const T &a, const T &b) + \relates QHash + \since 6.0 + \internal + + This method is being used by QHash to compare two keys. Returns true if the + keys \a a and \a b are considered equal for hashing purposes. + + The default implementation returns the result of (a == b). It can be reimplemented + for a certain type if the equality operator is not suitable for hashing purposes. + This is for example the case if the equality operator uses qFuzzyCompare to compare + floating point values. +*/ + + /*! \class QHash \inmodule QtCore diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 5dc88943fc..70e98bed60 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -560,7 +560,7 @@ struct Data return iterator{ this, bucket }; } else { Node &n = s.atOffset(offset); - if (n.key == key) + if (qHashEquals(n.key, key)) return iterator{ this, bucket }; } bucket = nextBucket(bucket); diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index 9cfa852ba2..a8b5e0f7bc 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -170,6 +170,12 @@ template inline size_t qHash(const T &t, size_t seed) noexcept(noexcept(qHash(t))) { return qHash(t) ^ seed; } +template +bool qHashEquals(const T &a, const T &b) +{ + return a == b; +} + namespace QtPrivate { struct QHashCombine -- cgit v1.2.3