summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2016-07-11 11:14:34 +0200
committerMarc Mutz <marc.mutz@kdab.com>2016-07-14 06:53:48 +0000
commitc2f4705f23ddccf075010edb0532fd73145b8b15 (patch)
treee35ca3cde5b3ae81b140dcb3d232067a988ee74e /src
parent89152c57d864c6767daa5aead2adb3ae6bee482b (diff)
Add qHash(QHash) and qHash(QMultiHash)
The hash function is carefully designed to give the same result as the straight-forward implementation of qHash(unordered_map), which we'll probably add at some point, namely: std::accumulate over a container of std::pair. This is one reason to use std:: and not QPair in the implemen- tation of qHash(QHash). The other is that qHash(QPair) uses a bad hash combiner, which may xor out the 'seed' from the result. We can't fix that until Qt 6, but the qHash(std::pair) overload uses the well-known boost::hash_combine algorithm (implemented in Qt as QtPrivate::QHashCombine), so we can use that. I also trust std::pair to work without problems with reference template arguments, while QPair only very recently gained a very basic auto-test for reference parameters. [ChangeLog][QtCore] Added qHash() overloads for QHash, QMultiHash. Change-Id: I90879d8a99cf1aadb6e84ecc0c3704f52f3691da Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/tools/qhash.cpp20
-rw-r--r--src/corelib/tools/qhash.h21
2 files changed, 41 insertions, 0 deletions
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 593a87e65d..abec9ebb79 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -2644,4 +2644,24 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW
\sa QHash::constFind()
*/
+/*!
+ \fn uint qHash(const QHash<Key, T> &key, uint seed = 0)
+ \since 5.8
+ \relates QHash
+
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+
+ Type \c T must be supported by qHash().
+*/
+
+/*!
+ \fn uint qHash(const QMultiHash<Key, T> &key, uint seed = 0)
+ \since 5.8
+ \relates QMultiHash
+
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+
+ Type \c T must be supported by qHash().
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 7abbeabeae..6a2d7bdd11 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -1095,6 +1095,27 @@ Q_INLINE_TEMPLATE int QMultiHash<Key, T>::count(const Key &key, const T &value)
Q_DECLARE_ASSOCIATIVE_ITERATOR(Hash)
Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Hash)
+template <class Key, class T>
+uint qHash(const QHash<Key, T> &key, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(std::declval<Key&>())) && noexcept(qHash(std::declval<T&>())))
+{
+ QtPrivate::QHashCombineCommutative hash;
+ 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));
+ }
+ return seed;
+}
+
+template <class Key, class T>
+inline uint qHash(const QMultiHash<Key, T> &key, uint seed = 0)
+ Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(std::declval<Key&>())) && noexcept(qHash(std::declval<T&>())))
+{
+ const QHash<Key, T> &key2 = key;
+ return qHash(key2, seed);
+}
+
QT_END_NAMESPACE
#if defined(Q_CC_MSVC)