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 <thiago.macieira@intel.com>
bb10
Ivan Solovev 2024-02-20 12:43:08 +01:00
parent 42b6fdfb52
commit e2e21bcb2d
4 changed files with 40 additions and 3 deletions

View File

@ -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.

View File

@ -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

View File

@ -8041,11 +8041,16 @@ void tst_QString::comparisonCompiles()
QTestPrivate::testAllComparisonOperatorsCompile<QString, QChar>();
QTestPrivate::testAllComparisonOperatorsCompile<QString, QLatin1StringView>();
QTestPrivate::testAllComparisonOperatorsCompile<QString, const char16_t *>();
QTestPrivate::testAllComparisonOperatorsCompile<QString, QStringView>();
QTestPrivate::testAllComparisonOperatorsCompile<QString, QUtf8StringView>();
#if !defined(QT_RESTRICTED_CAST_FROM_ASCII) && !defined(QT_NO_CAST_FROM_ASCII)
QTestPrivate::testAllComparisonOperatorsCompile<QString, QByteArrayView>();
QTestPrivate::testAllComparisonOperatorsCompile<QString, QByteArray>();
QTestPrivate::testAllComparisonOperatorsCompile<QString, const char *>();
#endif
#ifdef __cpp_char8_t
QTestPrivate::testAllComparisonOperatorsCompile<QString, const char8_t *>();
#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<const char16_t*>(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<const char8_t*>(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()};

View File

@ -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)