From 64bfc927b09b46bb7fc0dc6caf1bf1a4d4133ab4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 16 Apr 2021 17:49:20 -0700 Subject: QHash: fix qHash(std::pair) There were two problems here: first, qHash(std::pair) must be declared before qHashMulti that might call back to qHash(std::pair) (i.e., a pair with one element that is also a pair). But moving the declaration above causes the second problem: the noexcept expression can't refer to qHash functions that aren't declared yet. So we forward-declare a constexpr function for that result, but implement it far below. Fixes: QTBUG-92910 Change-Id: Ia8e48103a54446509e3bfffd16767ed2e29b026c Reviewed-by: Christian Kandeler Reviewed-by: Thiago Macieira --- src/corelib/tools/qhashfunctions.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index 4c2eba3e53..4f8e4066ee 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -114,10 +114,15 @@ constexpr inline bool HasQHashSingleArgOverload())), size_t> >> = true; +template static constexpr bool noexceptPairHash(); } Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHashBits(const void *p, size_t size, size_t seed = 0) noexcept; +// implementation below qHashMulti +template inline size_t qHash(const std::pair &key, size_t seed = 0) + noexcept(QHashPrivate::noexceptPairHash()); + // C++ builtin types Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(char key, size_t seed = 0) noexcept { return QHashPrivate::hash(size_t(key), seed); } @@ -290,8 +295,16 @@ inline size_t qHashRangeCommutative(InputIterator first, InputIterator last, siz return std::accumulate(first, last, seed, QtPrivate::QHashCombineCommutative()); } -template inline size_t qHash(const std::pair &key, size_t seed = 0) - noexcept(noexcept(qHash(key.first, seed)) && noexcept(qHash(key.second, seed))) +namespace QHashPrivate { +template static constexpr bool noexceptPairHash() +{ + size_t seed = 0; + return noexcept(qHash(std::declval(), seed)) && noexcept(qHash(std::declval(), seed)); +} +} // QHashPrivate + +template inline size_t qHash(const std::pair &key, size_t seed) + noexcept(QHashPrivate::noexceptPairHash()) { return qHashMulti(seed, key.first, key.second); } -- cgit v1.2.3