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.

Task-number: QTBUG-88966
Change-Id: I346cf0e6e923277a8b42a79e50342a1c2511fd80
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 5d8b586e73e37070b0303bee24372550854637eb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Lars Knoll 2020-12-03 09:14:27 +01:00 committed by Qt Cherry-pick Bot
parent 013abe3206
commit 793dbd8ee6
3 changed files with 22 additions and 1 deletions

View File

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

View File

@ -602,7 +602,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);

View File

@ -178,6 +178,12 @@ template <typename T, std::enable_if_t<QHashPrivate::HasQHashSingleArgOverload<T
size_t qHash(const T &t, size_t seed) noexcept(noexcept(qHash(t)))
{ return qHash(t) ^ seed; }
template<typename T>
bool qHashEquals(const T &a, const T &b)
{
return a == b;
}
namespace QtPrivate {
struct QHashCombine