From e2e21bcb2d1053e8a6477b99a60c41774b115c23 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Tue, 20 Feb 2024 12:43:08 +0100 Subject: [PATCH] QString: use comparison helper macros - missing string views [3/3] The comparison with QStringView works as is, there is no need to add explicit operators. Add the missing relational operators with QUtf8StringView. Once it is added, comparison of QString with u8"string literal" becomes ambiguous, so explicitly add operators for `const char8_t*` as well. This also makes the comparison with u8 string literals faster, because it now uses a view instead of constructing a QString. Adding QUtf8StringView overloads also makes comparison with `const char *` ambiguous if QT_RESTRICTED_CAST_FROM_ASCII is defined. To fix that, mark the overload as Q_WEAK_OVERLOAD. Luckily, we can just use the third Attributes parameter of the macro for that. Provide more unit-tests to cover the new relational operators. Task-number: QTBUG-117661 Change-Id: I60d1f4ad7ea607472deeb5c250e62f2bb7019268 Reviewed-by: Thiago Macieira --- src/corelib/text/qstring.cpp | 3 ++- src/corelib/text/qstring.h | 19 +++++++++++++++++++ .../auto/corelib/text/qstring/tst_qstring.cpp | 19 +++++++++++++++++++ .../tst_qstringapisymmetry.cpp | 2 -- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 0878e03b5b..dba6f6b298 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -1703,7 +1703,8 @@ void qtWarnAboutInvalidRegularExpression(const QString &pattern, const char *whe \ingroup string-processing \compares strong - \compareswith strong QChar QLatin1StringView {const char16_t *} + \compareswith strong QChar QLatin1StringView {const char16_t *} \ + QStringView QUtf8StringView \endcompareswith \compareswith strong QByteArray QByteArrayView {const char *} When comparing with byte arrays, their content is interpreted as utf-8. diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 4a07a134ca..6616bf5fe8 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -767,6 +767,25 @@ public: { return compareThreeWay(QStringView(s1), QStringView(s2)); } Q_DECLARE_STRONGLY_ORDERED(QString) + Q_WEAK_OVERLOAD + friend bool comparesEqual(const QString &s1, QUtf8StringView s2) noexcept + { return QtPrivate::equalStrings(s1, s2); } + Q_WEAK_OVERLOAD + friend Qt::strong_ordering compareThreeWay(const QString &s1, QUtf8StringView s2) noexcept + { + const int res = QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive); + return Qt::compareThreeWay(res, 0); + } + Q_DECLARE_STRONGLY_ORDERED(QString, QUtf8StringView, Q_WEAK_OVERLOAD) + +#ifdef __cpp_char8_t + friend bool comparesEqual(const QString &s1, const char8_t *s2) noexcept + { return comparesEqual(s1, QUtf8StringView(s2)); } + friend Qt::strong_ordering compareThreeWay(const QString &s1, const char8_t *s2) noexcept + { return compareThreeWay(s1, QUtf8StringView(s2)); } + Q_DECLARE_STRONGLY_ORDERED(QString, const char8_t *) +#endif // __cpp_char8_t + friend bool comparesEqual(const QString &s1, QLatin1StringView s2) noexcept { return (s1.size() == s2.size()) && QtPrivate::equalStrings(s1, s2); } friend Qt::strong_ordering diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index ae7a80dcc6..35bddf16a4 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -8041,11 +8041,16 @@ void tst_QString::comparisonCompiles() QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); #if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII) QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); #endif +#ifdef __cpp_char8_t + QTestPrivate::testAllComparisonOperatorsCompile(); +#endif } void tst_QString::compare_data() @@ -8258,6 +8263,9 @@ void tst_QString::comparisonMacros() QT_TEST_ALL_COMPARISON_OPS(s1, s2, expectedOrdering); + const QStringView s2sv(s2); + QT_TEST_ALL_COMPARISON_OPS(s1, s2sv, expectedOrdering); + if (!s2.contains(QChar(u'\0'))) { const char16_t *utfData = reinterpret_cast(s2.constData()); QT_TEST_ALL_COMPARISON_OPS(s1, utfData, expectedOrdering); @@ -8275,6 +8283,17 @@ void tst_QString::comparisonMacros() } const QByteArray u8s2 = s2.toUtf8(); + + const QUtf8StringView u8s2sv(u8s2.data(), u8s2.size()); + QT_TEST_ALL_COMPARISON_OPS(s1, u8s2sv, expectedOrdering); + +#ifdef __cpp_char8_t + if (!s2.contains(QChar(u'\0'))) { + const char8_t *char8data = reinterpret_cast(u8s2.constData()); + QT_TEST_ALL_COMPARISON_OPS(s1, char8data, expectedOrdering); + } +#endif // __cpp_char8_t + #if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII) QT_TEST_ALL_COMPARISON_OPS(s1, u8s2, expectedOrdering); const QByteArrayView u8s2view{u8s2.begin(), u8s2.size()}; diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 3b88fe176a..d4c89d3c30 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -70,8 +70,6 @@ MAKE_ALL(QChar, QByteArray) MAKE_ALL(QChar, const char*) MAKE_ALL(QChar, QUtf8StringView) -MAKE_ALL(QString, QUtf8StringView) - MAKE_ALL(QUtf8StringView, QChar) MAKE_ALL(QUtf8StringView, char16_t)