From a9d51298ae34ed05adb100983ed92bec07ce2ce5 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Mon, 18 Oct 2021 16:18:15 +0200 Subject: Fix metatype declaration for QHash/QMultiHash with no operator== When declaring metatypes, the metatype system tries to detect if the comparison operators for the given type exist and automatically register them. In case of QHash, the equality operator was enabled if the value type provides one. But the implementation needs equality operator of the key type as well. As a result, when the key type has no equality operator, the metatype system detects that the equality operator is available for the QHash itself, but the compilation for metatype registration fails when trying to instantiate the code that uses equality operator for the key. This is fixed by enabling equality operators for the QHash only when both the key and value types provide one. The same issue existed also for QMultiHash, with the difference, that QMultiHash didn't have the constraints even on the value type. So added checks for both. Fixes: QTBUG-96256 Pick-to: 6.2 Change-Id: Ib8b6d365223f2b3515cbcb1843524cd6f867a6ac Reviewed-by: Thiago Macieira --- src/corelib/tools/qhash.h | 20 ++++++++++++++------ .../corelib/tools/collections/tst_collections.cpp | 10 ++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index fb4b3f3198..ecbdfe4fb8 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -831,8 +831,8 @@ public: void swap(QHash &other) noexcept { qSwap(d, other.d); } #ifndef Q_CLANG_QDOC - template - QTypeTraits::compare_eq_result_container operator==(const QHash &other) const noexcept + template + QTypeTraits::compare_eq_result_container operator==(const QHash &other) const noexcept { if (d == other.d) return true; @@ -847,8 +847,8 @@ public: // all values must be the same as size is the same return true; } - template - QTypeTraits::compare_eq_result_container operator!=(const QHash &other) const noexcept + template + QTypeTraits::compare_eq_result_container operator!=(const QHash &other) const noexcept { return !(*this == other); } #else bool operator==(const QHash &other) const; @@ -1306,7 +1306,9 @@ public: } void swap(QMultiHash &other) noexcept { qSwap(d, other.d); qSwap(m_size, other.m_size); } - bool operator==(const QMultiHash &other) const noexcept +#ifndef Q_CLANG_QDOC + template + QTypeTraits::compare_eq_result_container operator==(const QMultiHash &other) const noexcept { if (d == other.d) return true; @@ -1339,7 +1341,13 @@ public: // all values must be the same as size is the same return true; } - bool operator!=(const QMultiHash &other) const noexcept { return !(*this == other); } + template + QTypeTraits::compare_eq_result_container operator!=(const QMultiHash &other) const noexcept + { return !(*this == other); } +#else + bool operator==(const QMultiHash &other) const; + bool operator!=(const QMultiHash &other) const; +#endif // Q_CLANG_QDOC inline qsizetype size() const noexcept { return m_size; } diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index 80d1d90f2a..d4551785e9 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -253,11 +253,9 @@ Q_DECLARE_METATYPE(NoCmpParamRecursiveMapK); Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiMapV); Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiMapK); Q_DECLARE_METATYPE(NoCmpParamRecursiveHashK); -// TODO: fix, this requires operator== from key type (QTBUG-96256) -// Q_DECLARE_METATYPE(NoCmpParamRecursiveHashV); +Q_DECLARE_METATYPE(NoCmpParamRecursiveHashV); Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiHashK); -// TODO: fix, this requires operator== from key type (QTBUG-96256) -// Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiHashK); +Q_DECLARE_METATYPE(NoCmpParamRecursiveMultiHashV); Q_DECLARE_METATYPE(NoCmpRecursiveList); // TODO: fix, this requires operator== (QTBUG-96257) @@ -287,9 +285,9 @@ static_assert(!QTypeTraits::has_operator_equal_v); static_assert(!QTypeTraits::has_operator_equal_v); static_assert(!QTypeTraits::has_operator_equal_v); static_assert(!QTypeTraits::has_operator_equal_v); -static_assert(QTypeTraits::has_operator_equal_v); +static_assert(!QTypeTraits::has_operator_equal_v); static_assert(!QTypeTraits::has_operator_equal_v); -static_assert(QTypeTraits::has_operator_equal_v); +static_assert(!QTypeTraits::has_operator_equal_v); static_assert(!QTypeTraits::has_operator_equal_v); static_assert(!QTypeTraits::has_operator_equal_v); -- cgit v1.2.3