QLatin1String: fix qt_compare_strings(QLatin1String, QLatin1String) for null strings
qstrcmp sorts null strings before empty ones, while the Qt string classes consider them equal. The qt_compare_strings() overload for QLatin1String was using qstrcmp(), but is supposed to implement the semantics that Qt string classes use, so we need to add an extra check. Was uncovered by tests for QLatin1String::startsWith(), but added a new test for qCompareStrings() now, which is a bit more complicated than desired, due to the lack of QUtf8String. Change-Id: I0493c4491df928a68861a1bc7f0962f1c870a416 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>bb10
parent
5677b70eee
commit
979f9f4d34
|
|
@ -695,6 +695,8 @@ static int qt_compare_strings(QStringView lhs, QLatin1String rhs, Qt::CaseSensit
|
|||
|
||||
static int qt_compare_strings(QLatin1String lhs, QLatin1String rhs, Qt::CaseSensitivity cs) Q_DECL_NOTHROW
|
||||
{
|
||||
if (lhs.isEmpty())
|
||||
return lencmp(0, rhs.size());
|
||||
const auto l = std::min(lhs.size(), rhs.size());
|
||||
int r;
|
||||
if (cs == Qt::CaseSensitive)
|
||||
|
|
|
|||
|
|
@ -319,6 +319,9 @@ void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty)
|
|||
QTest::newRow("null <> empty") << QStringRef() << QLatin1String()
|
||||
<< QStringRef(&empty) << QLatin1String("")
|
||||
<< 0 << 0;
|
||||
QTest::newRow("empty <> null") << QStringRef(&empty) << QLatin1String("")
|
||||
<< QStringRef() << QLatin1String()
|
||||
<< 0 << 0;
|
||||
}
|
||||
|
||||
#define ROW(lhs, rhs) \
|
||||
|
|
@ -362,6 +365,38 @@ struct has_nothrow_compare {
|
|||
enum { value = is_utf8_encoded<LHS>::value == is_utf8_encoded<RHS>::value };
|
||||
};
|
||||
|
||||
template <typename LHS, typename RHS>
|
||||
struct has_qCompareStrings {
|
||||
enum { value = !std::is_same<LHS, QChar>::value && !std::is_same<RHS, QChar>::value &&
|
||||
!is_utf8_encoded<LHS>::value && !is_utf8_encoded<RHS>::value };
|
||||
};
|
||||
|
||||
template <typename LHS, typename RHS>
|
||||
using if_has_qCompareStrings = typename std::enable_if<has_qCompareStrings<LHS, RHS>::value, bool>::type;
|
||||
|
||||
template <typename LHS, typename RHS>
|
||||
using if_lacks_qCompareStrings = typename std::enable_if<!has_qCompareStrings<LHS, RHS>::value, bool>::type;
|
||||
|
||||
static inline Q_DECL_CONSTEXPR int sign(int x) Q_DECL_NOTHROW
|
||||
{
|
||||
return x < 0 ? -1 :
|
||||
x > 0 ? +1 :
|
||||
/*else*/ 0 ;
|
||||
}
|
||||
|
||||
template <typename LHS, typename RHS, if_has_qCompareStrings<LHS, RHS> = true>
|
||||
int qCompareStringsWrapper(const LHS &lhs, const RHS &rhs, Qt::CaseSensitivity cs, int)
|
||||
Q_DECL_NOEXCEPT_EXPR(noexcept(qCompareStrings(lhs, rhs, cs)))
|
||||
{
|
||||
return qCompareStrings(lhs, rhs, cs);
|
||||
}
|
||||
|
||||
template <typename LHS, typename RHS, if_lacks_qCompareStrings<LHS, RHS> = true>
|
||||
int qCompareStringsWrapper(const LHS &, const RHS &, Qt::CaseSensitivity, int result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename LHS, typename RHS>
|
||||
void tst_QStringApiSymmetry::compare_impl() const
|
||||
{
|
||||
|
|
@ -370,6 +405,7 @@ void tst_QStringApiSymmetry::compare_impl() const
|
|||
QFETCH(QStringRef, rhsUnicode);
|
||||
QFETCH(QLatin1String, rhsLatin1);
|
||||
QFETCH(int, caseSensitiveCompareResult);
|
||||
QFETCH(const int, caseInsensitiveCompareResult);
|
||||
|
||||
const auto lhsU8 = lhsUnicode.toUtf8();
|
||||
const auto rhsU8 = rhsUnicode.toUtf8();
|
||||
|
|
@ -386,6 +422,10 @@ void tst_QStringApiSymmetry::compare_impl() const
|
|||
# define QVERIFY_NOEXCEPT(expr)
|
||||
#endif
|
||||
|
||||
QCOMPARE(sign(qCompareStringsWrapper(lhs, rhs, Qt::CaseSensitive, caseSensitiveCompareResult)),
|
||||
sign(caseSensitiveCompareResult));
|
||||
QCOMPARE(sign(qCompareStringsWrapper(lhs, rhs, Qt::CaseInsensitive, caseInsensitiveCompareResult)),
|
||||
sign(caseInsensitiveCompareResult));
|
||||
#define CHECK(op) \
|
||||
QVERIFY_NOEXCEPT(lhs op rhs); \
|
||||
do { if (caseSensitiveCompareResult op 0) { \
|
||||
|
|
|
|||
Loading…
Reference in New Issue