Fix qHash(QMultiHash)

The old code was trying to convert a multi hash to a QHash. While
that worked in Qt 5 it won't compile in Qt 6 anymore.

QHashCombineCommutative also can't be used with a std::pair.
ADL won't find the correct instance with a namespaced build,
as qHash(std::pair) is defined after QHashCommutative. Fix
the code to compile and work correctly.

Change-Id: Ice2bc3ab4244e310cbbb5e0f31fc11eb14f5faf3
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Lars Knoll 2020-10-26 09:18:00 +01:00
parent ba1266baec
commit a9c52dbdf4
2 changed files with 24 additions and 7 deletions

View File

@ -1848,21 +1848,28 @@ template <class Key, class T>
size_t qHash(const QHash<Key, T> &key, size_t seed = 0)
noexcept(noexcept(qHash(std::declval<Key&>())) && noexcept(qHash(std::declval<T&>())))
{
QtPrivate::QHashCombineCommutative hash;
size_t hash = 0;
for (auto it = key.begin(), end = key.end(); it != end; ++it) {
const Key &k = it.key();
const T &v = it.value();
seed = hash(seed, std::pair<const Key&, const T&>(k, v));
QtPrivate::QHashCombine combine;
size_t h = combine(seed, it.key());
// use + to keep the result independent of the ordering of the keys
hash += combine(h, it.value());
}
return seed;
return hash;
}
template <class Key, class T>
inline size_t qHash(const QMultiHash<Key, T> &key, size_t seed = 0)
noexcept(noexcept(qHash(std::declval<Key&>())) && noexcept(qHash(std::declval<T&>())))
{
const QHash<Key, T> &key2 = key;
return qHash(key2, seed);
size_t hash = 0;
for (auto it = key.begin(), end = key.end(); it != end; ++it) {
QtPrivate::QHashCombine combine;
size_t h = combine(seed, it.key());
// use + to keep the result independent of the ordering of the keys
hash += combine(h, it.value());
}
return hash;
}
QT_END_NAMESPACE

View File

@ -73,6 +73,7 @@ private slots:
void emplace();
void badHashFunction();
void hashOfHash();
};
struct IdentityTracker {
@ -1754,5 +1755,14 @@ void tst_QHash::badHashFunction()
}
void tst_QHash::hashOfHash()
{
QHash<int, int> hash;
(void)qHash(hash);
QMultiHash<int, int> multiHash;
(void)qHash(multiHash);
}
QTEST_APPLESS_MAIN(tst_QHash)
#include "tst_qhash.moc"