diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index b7182ac6d4..9056d24102 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -13,6 +13,10 @@ #include // for std::hash #include // For std::pair +#ifdef __cpp_concepts +# include +#endif + #if 0 #pragma qt_class(QHashFunctions) #endif @@ -46,6 +50,15 @@ private: size_t data; }; +// Whether, ∀ t of type T && ∀ seed, qHash(Key(t), seed) == qHash(t, seed) +template struct QHashHeterogeneousSearch : std::false_type {}; + +// Specializations +template <> struct QHashHeterogeneousSearch : std::true_type {}; +template <> struct QHashHeterogeneousSearch : std::true_type {}; +template <> struct QHashHeterogeneousSearch : std::true_type {}; +template <> struct QHashHeterogeneousSearch : std::true_type {}; + namespace QHashPrivate { Q_DECL_CONST_FUNCTION constexpr size_t hash(size_t key, size_t seed) noexcept @@ -217,12 +230,35 @@ size_t qHash(const T &t, size_t seed) noexcept(noexcept(qHash(t))) { return qHash(t) ^ seed; } #endif // < Qt 7 +namespace QHashPrivate { +#ifdef __cpp_concepts +template concept HeterogeneouslySearchableWithHelper = + // if Key and T are not the same (member already exists) + !std::is_same_v + // but are comparable amongst each other + && std::equality_comparable_with + // and supports heteregenous hashing + && QHashHeterogeneousSearch::value; +template concept HeterogeneouslySearchableWith = + HeterogeneouslySearchableWithHelper, q20::remove_cvref_t>; +#else +template constexpr bool HeterogeneouslySearchableWith = false; +#endif +} + template bool qHashEquals(const T &a, const T &b) { return a == b; } +template +std::enable_if_t, bool> +qHashEquals(const T1 &a, const T2 &b) +{ + return a == b; +} + namespace QtPrivate { struct QHashCombine