diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 436aa18cfd0..6daab908bb6 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -5,6 +5,7 @@ #ifndef QMAP_H #define QMAP_H +#include #include #include #include @@ -777,6 +778,31 @@ public: auto result = d->m.equal_range(akey); return {const_iterator(result.first), const_iterator(result.second)}; } + +private: +#ifdef Q_QDOC + friend size_t qHash(const QMap &key, size_t seed = 0); +#else +# ifdef Q_CC_GHS + // GHS tries to intantiate qHash() for the noexcept running into a + // non-SFINAE'ed hard error... Create an artificial SFINAE context as a + // work-around: + template , bool> = true> + friend QtPrivate::QHashMultiReturnType +# else + using M = QMap; + friend size_t +# endif + qHash(const M &key, size_t seed = 0) + noexcept(QHashPrivate::noexceptPairHash()) + { + if (!key.d) + return seed; + // don't use qHashRange to avoid its compile-time overhead: + return std::accumulate(key.d->m.begin(), key.d->m.end(), seed, + QtPrivate::QHashCombine{}); + } +#endif // !Q_QDOC }; Q_DECLARE_ASSOCIATIVE_ITERATOR(Map) @@ -788,6 +814,7 @@ qsizetype erase_if(QMap &map, Predicate pred) return QtPrivate::associative_erase_if(map, pred); } + // // QMultiMap // diff --git a/src/corelib/tools/qmap.qdoc b/src/corelib/tools/qmap.qdoc index 9b5a8588cf4..d4779ba28c9 100644 --- a/src/corelib/tools/qmap.qdoc +++ b/src/corelib/tools/qmap.qdoc @@ -1389,3 +1389,12 @@ Returns the number of elements removed, if any. */ + +/*! + \fn template QMap::qHash(const QMap &key, size_t seed) + \since 6.8 + + Returns the hash value for \a key, using \a seed to seed the calculation. + + Types \c Key and \c T must be supported by qHash(). +*/ diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index ef2a5383d3c..6950dcf7056 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -640,16 +640,19 @@ void tst_QMap::operator_eq() QMap b; QVERIFY(a == b); + QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); a.insert(1,1); b.insert(1,1); QVERIFY(a == b); + QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); a.insert(0,1); b.insert(0,1); QVERIFY(a == b); + QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); // compare for inequality: @@ -672,6 +675,7 @@ void tst_QMap::operator_eq() QMap b; QVERIFY(a == b); + QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); a.insert("Hello", "World"); @@ -680,6 +684,7 @@ void tst_QMap::operator_eq() b.insert("Hello", "World"); QVERIFY(a == b); + QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); a.insert("Goodbye", "cruel world"); @@ -696,6 +701,7 @@ void tst_QMap::operator_eq() // empty keys and null keys match: b.insert(QString(""), QString()); QVERIFY(a == b); + QCOMPARE(qHash(a), qHash(b)); QVERIFY(!(a != b)); }