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 <thiago.macieira@intel.com>
This commit is contained in:
Sona Kurazyan 2021-10-18 16:18:15 +02:00
parent a182897f77
commit a9d51298ae
2 changed files with 18 additions and 12 deletions

View File

@ -831,8 +831,8 @@ public:
void swap(QHash &other) noexcept { qSwap(d, other.d); }
#ifndef Q_CLANG_QDOC
template <typename U = T>
QTypeTraits::compare_eq_result_container<QHash, U> operator==(const QHash &other) const noexcept
template <typename AKey = Key, typename AT = T>
QTypeTraits::compare_eq_result_container<QHash, AKey, AT> 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 <typename U = T>
QTypeTraits::compare_eq_result_container<QHash, U> operator!=(const QHash &other) const noexcept
template <typename AKey = Key, typename AT = T>
QTypeTraits::compare_eq_result_container<QHash, AKey, AT> 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 <typename AKey = Key, typename AT = T>
QTypeTraits::compare_eq_result_container<QMultiHash, AKey, AT> 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 <typename AKey = Key, typename AT = T>
QTypeTraits::compare_eq_result_container<QMultiHash, AKey, AT> 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; }

View File

@ -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<NoCmpParamRecursiveMapV>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMapK>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiMapV>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiMapK>);
static_assert(QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveHashV>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveHashV>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveHashK>);
static_assert(QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiHashV>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiHashV>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpParamRecursiveMultiHashK>);
static_assert(!QTypeTraits::has_operator_equal_v<NoCmpRecursiveList>);