summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qhash.h21
-rw-r--r--tests/auto/corelib/tools/qhash/tst_qhash.cpp10
2 files changed, 24 insertions, 7 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index cee58a0f2f9..67b3e026df8 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -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
diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
index d5a8db7553f..d63ed7043ec 100644
--- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp
+++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
@@ -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"