QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH: use unqualified qHash() lookup
... instead of QT_PREPEND_NAMESPACE(qHash), which is qualified (prepends at least '::'), and therefore disables ADL. This is not a problem as long as we wrote our qHash() overloads as free functions (incl. non-hidden friends), but it should™ fail for hidden friends, so use the old using-std::swap() trick to bring QT_PREPEND_NAMESPACE(qHash) into scope, proceeding with an unqualified lookup. Pick-to: 6.2 Change-Id: I00860b2313699849f86bfe3dd9f41db4ce993cd3 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
95ccdfa432
commit
ccaeffe565
@ -251,6 +251,9 @@ struct QNothrowHashable : std::false_type {};
|
||||
template <typename T>
|
||||
struct QNothrowHashable<T, std::enable_if_t<QNothrowHashableHelper_v<T>>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool QNothrowHashable_v = QNothrowHashable<T>::value;
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
template <typename... T>
|
||||
@ -317,15 +320,15 @@ template <typename T1, typename T2> inline size_t qHash(const std::pair<T1, T2>
|
||||
using argument_type = QT_PREPEND_NAMESPACE(Class); \
|
||||
using result_type = size_t; \
|
||||
size_t operator()(Arguments s) const \
|
||||
noexcept(noexcept(QT_PREPEND_NAMESPACE(qHash)(s))) \
|
||||
noexcept(QT_PREPEND_NAMESPACE( \
|
||||
QtPrivate::QNothrowHashable_v)<argument_type>) \
|
||||
{ \
|
||||
/* this seeds qHash with the result of */ \
|
||||
/* std::hash applied to an int, to reap */ \
|
||||
/* any protection against predictable hash */ \
|
||||
/* values the std implementation may provide */ \
|
||||
return QT_PREPEND_NAMESPACE(qHash)(s, \
|
||||
QT_PREPEND_NAMESPACE(qHash)( \
|
||||
std::hash<int>{}(0))); \
|
||||
using QT_PREPEND_NAMESPACE(qHash); \
|
||||
return qHash(s, qHash(std::hash<int>{}(0))); \
|
||||
} \
|
||||
}; \
|
||||
} \
|
||||
|
@ -303,8 +303,34 @@ void tst_QHashFunctions::rangeCommutative()
|
||||
}
|
||||
}
|
||||
|
||||
// QVarLengthArray these days has a qHash() as a hidden friend.
|
||||
// This checks that QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH can deal with that:
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QVarLengthArray<QVector<int>>)
|
||||
QT_END_NAMESPACE
|
||||
|
||||
void tst_QHashFunctions::stdHash()
|
||||
{
|
||||
{
|
||||
std::unordered_set<QVarLengthArray<QVector<int>>> s = {
|
||||
{
|
||||
{0, 1, 2},
|
||||
{42, 43, 44},
|
||||
{},
|
||||
}, {
|
||||
{11, 12, 13},
|
||||
{},
|
||||
},
|
||||
};
|
||||
QCOMPARE(s.size(), 2UL);
|
||||
s.insert({
|
||||
{11, 12, 13},
|
||||
{},
|
||||
});
|
||||
QCOMPARE(s.size(), 2UL);
|
||||
}
|
||||
|
||||
{
|
||||
std::unordered_set<QString> s = {QStringLiteral("Hello"), QStringLiteral("World")};
|
||||
QCOMPARE(s.size(), 2UL);
|
||||
|
Loading…
Reference in New Issue
Block a user