QString: use comparison helper macros - trivial changes [1/3]
Replace the hidden friend relational operators with hidden friend helper functions and comparison helper macros. Provide more unit-tests for the updated types. This enables operator<=> in C++20 builds. Task-number: QTBUG-117661 Change-Id: I17329cd6422f272a435fc1da241203581eef7fbb Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
6d08db8666
commit
755581e2e7
@ -1702,6 +1702,10 @@ void qtWarnAboutInvalidRegularExpression(const QString &pattern, const char *whe
|
||||
\ingroup shared
|
||||
\ingroup string-processing
|
||||
|
||||
\compares strong
|
||||
\compareswith strong QChar QLatin1StringView {const char16_t *}
|
||||
\endcompareswith
|
||||
|
||||
QString stores a string of 16-bit \l{QChar}s, where each QChar
|
||||
corresponds to one UTF-16 code unit. (Unicode characters
|
||||
with code values above 65535 are stored using surrogate pairs,
|
||||
@ -4052,10 +4056,10 @@ QString &QString::replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator==(const QString &s1, const QString &s2)
|
||||
\fn bool QString::operator==(const QString &lhs, const QString &rhs)
|
||||
\overload operator==()
|
||||
|
||||
Returns \c true if string \a s1 is equal to string \a s2; otherwise
|
||||
Returns \c true if string \a lhs is equal to string \a rhs; otherwise
|
||||
returns \c false.
|
||||
|
||||
\include qstring.cpp compare-isNull-vs-isEmpty
|
||||
@ -4064,20 +4068,20 @@ QString &QString::replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator==(const QString &s1, QLatin1StringView s2)
|
||||
\fn bool QString::operator==(const QString &lhs, const QLatin1StringView &rhs)
|
||||
|
||||
\overload operator==()
|
||||
|
||||
Returns \c true if \a s1 is equal to \a s2; otherwise
|
||||
Returns \c true if \a lhs is equal to \a rhs; otherwise
|
||||
returns \c false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator==(QLatin1StringView s1, const QString &s2)
|
||||
\fn bool QString::operator==(const QLatin1StringView &lhs, const QString &rhs)
|
||||
|
||||
\overload operator==()
|
||||
|
||||
Returns \c true if \a s1 is equal to \a s2; otherwise
|
||||
Returns \c true if \a lhs is equal to \a rhs; otherwise
|
||||
returns \c false.
|
||||
*/
|
||||
|
||||
@ -4111,31 +4115,31 @@ QString &QString::replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator<(const QString &s1, const QString &s2)
|
||||
\fn bool QString::operator<(const QString &lhs, const QString &rhs)
|
||||
|
||||
\overload operator<()
|
||||
|
||||
Returns \c true if string \a s1 is lexically less than string
|
||||
\a s2; otherwise returns \c false.
|
||||
Returns \c true if string \a lhs is lexically less than string
|
||||
\a rhs; otherwise returns \c false.
|
||||
|
||||
\sa {Comparing Strings}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator<(const QString &s1, QLatin1StringView s2)
|
||||
\fn bool QString::operator<(const QString &lhs, const QLatin1StringView &rhs)
|
||||
|
||||
\overload operator<()
|
||||
|
||||
Returns \c true if \a s1 is lexically less than \a s2;
|
||||
Returns \c true if \a lhs is lexically less than \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator<(QLatin1StringView s1, const QString &s2)
|
||||
\fn bool QString::operator<(const QLatin1StringView &lhs, const QString &rhs)
|
||||
|
||||
\overload operator<()
|
||||
|
||||
Returns \c true if \a s1 is lexically less than \a s2;
|
||||
Returns \c true if \a lhs is lexically less than \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
@ -4169,29 +4173,29 @@ QString &QString::replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity
|
||||
go through QObject::tr(), for example.
|
||||
*/
|
||||
|
||||
/*! \fn bool QString::operator<=(const QString &s1, const QString &s2)
|
||||
/*! \fn bool QString::operator<=(const QString &lhs, const QString &rhs)
|
||||
|
||||
Returns \c true if string \a s1 is lexically less than or equal to
|
||||
string \a s2; otherwise returns \c false.
|
||||
Returns \c true if string \a lhs is lexically less than or equal to
|
||||
string \a rhs; otherwise returns \c false.
|
||||
|
||||
\sa {Comparing Strings}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator<=(const QString &s1, QLatin1StringView s2)
|
||||
\fn bool QString::operator<=(const QString &lhs, const QLatin1StringView &rhs)
|
||||
|
||||
\overload operator<=()
|
||||
|
||||
Returns \c true if \a s1 is lexically less than or equal to \a s2;
|
||||
Returns \c true if \a lhs is lexically less than or equal to \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator<=(QLatin1StringView s1, const QString &s2)
|
||||
\fn bool QString::operator<=(const QLatin1StringView &lhs, const QString &rhs)
|
||||
|
||||
\overload operator<=()
|
||||
|
||||
Returns \c true if \a s1 is lexically less than or equal to \a s2;
|
||||
Returns \c true if \a lhs is lexically less than or equal to \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
@ -4222,29 +4226,29 @@ QString &QString::replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity
|
||||
go through QObject::tr(), for example.
|
||||
*/
|
||||
|
||||
/*! \fn bool QString::operator>(const QString &s1, const QString &s2)
|
||||
/*! \fn bool QString::operator>(const QString &lhs, const QString &rhs)
|
||||
|
||||
Returns \c true if string \a s1 is lexically greater than string \a s2;
|
||||
Returns \c true if string \a lhs is lexically greater than string \a rhs;
|
||||
otherwise returns \c false.
|
||||
|
||||
\sa {Comparing Strings}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator>(const QString &s1, QLatin1StringView s2)
|
||||
\fn bool QString::operator>(const QString &lhs, const QLatin1StringView &rhs)
|
||||
|
||||
\overload operator>()
|
||||
|
||||
Returns \c true if \a s1 is lexically greater than \a s2;
|
||||
Returns \c true if \a lhs is lexically greater than \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator>(QLatin1StringView s1, const QString &s2)
|
||||
\fn bool QString::operator>(const QLatin1StringView &lhs, const QString &rhs)
|
||||
|
||||
\overload operator>()
|
||||
|
||||
Returns \c true if \a s1 is lexically greater than \a s2;
|
||||
Returns \c true if \a lhs is lexically greater than \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
@ -4275,29 +4279,29 @@ QString &QString::replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity
|
||||
for example.
|
||||
*/
|
||||
|
||||
/*! \fn bool QString::operator>=(const QString &s1, const QString &s2)
|
||||
/*! \fn bool QString::operator>=(const QString &lhs, const QString &rhs)
|
||||
|
||||
Returns \c true if string \a s1 is lexically greater than or equal to
|
||||
string \a s2; otherwise returns \c false.
|
||||
Returns \c true if string \a lhs is lexically greater than or equal to
|
||||
string \a rhs; otherwise returns \c false.
|
||||
|
||||
\sa {Comparing Strings}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator>=(const QString &s1, QLatin1StringView s2)
|
||||
\fn bool QString::operator>=(const QString &lhs, const QLatin1StringView &rhs)
|
||||
|
||||
\overload operator>=()
|
||||
|
||||
Returns \c true if \a s1 is lexically greater than or equal to \a s2;
|
||||
Returns \c true if \a lhs is lexically greater than or equal to \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn bool QString::operator>=(QLatin1StringView s1, const QString &s2)
|
||||
\fn bool QString::operator>=(const QLatin1StringView &lhs, const QString &rhs)
|
||||
|
||||
\overload operator>=()
|
||||
|
||||
Returns \c true if \a s1 is lexically greater than or equal to \a s2;
|
||||
Returns \c true if \a lhs is lexically greater than or equal to \a rhs;
|
||||
otherwise returns \c false.
|
||||
*/
|
||||
|
||||
@ -4328,17 +4332,17 @@ QString &QString::replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity
|
||||
for example.
|
||||
*/
|
||||
|
||||
/*! \fn bool QString::operator!=(const QString &s1, const QString &s2)
|
||||
/*! \fn bool QString::operator!=(const QString &lhs, const QString &rhs)
|
||||
|
||||
Returns \c true if string \a s1 is not equal to string \a s2;
|
||||
Returns \c true if string \a lhs is not equal to string \a rhs;
|
||||
otherwise returns \c false.
|
||||
|
||||
\sa {Comparing Strings}
|
||||
*/
|
||||
|
||||
/*! \fn bool QString::operator!=(const QString &s1, QLatin1StringView s2)
|
||||
/*! \fn bool QString::operator!=(const QString &lhs, const QLatin1StringView &rhs)
|
||||
|
||||
Returns \c true if string \a s1 is not equal to string \a s2.
|
||||
Returns \c true if string \a lhs is not equal to string \a rhs.
|
||||
Otherwise returns \c false.
|
||||
|
||||
\overload operator!=()
|
||||
|
@ -12,6 +12,7 @@
|
||||
#endif
|
||||
|
||||
#include <QtCore/qchar.h>
|
||||
#include <QtCore/qcompare.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qbytearrayview.h>
|
||||
#include <QtCore/qarraydata.h>
|
||||
@ -760,78 +761,44 @@ public:
|
||||
static QString number(qulonglong, int base=10);
|
||||
static QString number(double, char format='g', int precision=6);
|
||||
|
||||
friend bool operator==(const QString &s1, const QString &s2) noexcept
|
||||
{ return (s1.size() == s2.size()) && QtPrivate::equalStrings(s1, s2); }
|
||||
friend bool operator< (const QString &s1, const QString &s2) noexcept
|
||||
{ return QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) < 0; }
|
||||
friend bool operator> (const QString &s1, const QString &s2) noexcept { return s2 < s1; }
|
||||
friend bool operator!=(const QString &s1, const QString &s2) noexcept { return !(s1 == s2); }
|
||||
friend bool operator<=(const QString &s1, const QString &s2) noexcept { return !(s1 > s2); }
|
||||
friend bool operator>=(const QString &s1, const QString &s2) noexcept { return !(s1 < s2); }
|
||||
friend bool comparesEqual(const QString &s1, const QString &s2) noexcept
|
||||
{ return comparesEqual(QStringView(s1), QStringView(s2)); }
|
||||
friend Qt::strong_ordering compareThreeWay(const QString &s1, const QString &s2) noexcept
|
||||
{ return compareThreeWay(QStringView(s1), QStringView(s2)); }
|
||||
Q_DECLARE_STRONGLY_ORDERED(QString)
|
||||
|
||||
friend bool operator==(const QString &s1, QLatin1StringView s2) noexcept
|
||||
friend bool comparesEqual(const QString &s1, QLatin1StringView s2) noexcept
|
||||
{ return (s1.size() == s2.size()) && QtPrivate::equalStrings(s1, s2); }
|
||||
friend bool operator< (const QString &s1, QLatin1StringView s2) noexcept
|
||||
{ return QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) < 0; }
|
||||
friend bool operator> (const QString &s1, QLatin1StringView s2) noexcept
|
||||
{ return QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive) > 0; }
|
||||
friend bool operator!=(const QString &s1, QLatin1StringView s2) noexcept { return !(s1 == s2); }
|
||||
friend bool operator<=(const QString &s1, QLatin1StringView s2) noexcept { return !(s1 > s2); }
|
||||
friend bool operator>=(const QString &s1, QLatin1StringView s2) noexcept { return !(s1 < s2); }
|
||||
|
||||
friend bool operator==(QLatin1StringView s1, const QString &s2) noexcept { return s2 == s1; }
|
||||
friend bool operator< (QLatin1StringView s1, const QString &s2) noexcept { return s2 > s1; }
|
||||
friend bool operator> (QLatin1StringView s1, const QString &s2) noexcept { return s2 < s1; }
|
||||
friend bool operator!=(QLatin1StringView s1, const QString &s2) noexcept { return s2 != s1; }
|
||||
friend bool operator<=(QLatin1StringView s1, const QString &s2) noexcept { return s2 >= s1; }
|
||||
friend bool operator>=(QLatin1StringView s1, const QString &s2) noexcept { return s2 <= s1; }
|
||||
friend Qt::strong_ordering
|
||||
compareThreeWay(const QString &s1, QLatin1StringView s2) noexcept
|
||||
{
|
||||
const int res = QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive);
|
||||
return Qt::compareThreeWay(res, 0);
|
||||
}
|
||||
Q_DECLARE_STRONGLY_ORDERED(QString, QLatin1StringView)
|
||||
|
||||
// Check isEmpty() instead of isNull() for backwards compatibility.
|
||||
friend bool operator==(const QString &s1, std::nullptr_t) noexcept { return s1.isEmpty(); }
|
||||
friend bool operator!=(const QString &s1, std::nullptr_t) noexcept { return !s1.isEmpty(); }
|
||||
friend bool operator< (const QString & , std::nullptr_t) noexcept { return false; }
|
||||
friend bool operator> (const QString &s1, std::nullptr_t) noexcept { return !s1.isEmpty(); }
|
||||
friend bool operator<=(const QString &s1, std::nullptr_t) noexcept { return s1.isEmpty(); }
|
||||
friend bool operator>=(const QString & , std::nullptr_t) noexcept { return true; }
|
||||
friend bool operator==(std::nullptr_t, const QString &s2) noexcept { return s2 == nullptr; }
|
||||
friend bool operator!=(std::nullptr_t, const QString &s2) noexcept { return s2 != nullptr; }
|
||||
friend bool operator< (std::nullptr_t, const QString &s2) noexcept { return s2 > nullptr; }
|
||||
friend bool operator> (std::nullptr_t, const QString &s2) noexcept { return s2 < nullptr; }
|
||||
friend bool operator<=(std::nullptr_t, const QString &s2) noexcept { return s2 >= nullptr; }
|
||||
friend bool operator>=(std::nullptr_t, const QString &s2) noexcept { return s2 <= nullptr; }
|
||||
friend bool comparesEqual(const QString &s1, std::nullptr_t) noexcept
|
||||
{ return s1.isEmpty(); }
|
||||
friend Qt::strong_ordering compareThreeWay(const QString &s1, std::nullptr_t) noexcept
|
||||
{ return s1.isEmpty() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
|
||||
Q_DECLARE_STRONGLY_ORDERED(QString, std::nullptr_t)
|
||||
|
||||
friend bool operator==(const QString &s1, const char16_t *s2) noexcept { return s1 == QStringView(s2); }
|
||||
friend bool operator!=(const QString &s1, const char16_t *s2) noexcept { return s1 != QStringView(s2); }
|
||||
friend bool operator< (const QString &s1, const char16_t *s2) noexcept { return s1 < QStringView(s2); }
|
||||
friend bool operator> (const QString &s1, const char16_t *s2) noexcept { return s1 > QStringView(s2); }
|
||||
friend bool operator<=(const QString &s1, const char16_t *s2) noexcept { return s1 <= QStringView(s2); }
|
||||
friend bool operator>=(const QString &s1, const char16_t *s2) noexcept { return s1 >= QStringView(s2); }
|
||||
|
||||
friend bool operator==(const char16_t *s1, const QString &s2) noexcept { return s2 == s1; }
|
||||
friend bool operator!=(const char16_t *s1, const QString &s2) noexcept { return s2 != s1; }
|
||||
friend bool operator< (const char16_t *s1, const QString &s2) noexcept { return s2 > s1; }
|
||||
friend bool operator> (const char16_t *s1, const QString &s2) noexcept { return s2 < s1; }
|
||||
friend bool operator<=(const char16_t *s1, const QString &s2) noexcept { return s2 >= s1; }
|
||||
friend bool operator>=(const char16_t *s1, const QString &s2) noexcept { return s2 <= s1; }
|
||||
friend bool comparesEqual(const QString &s1, const char16_t *s2) noexcept
|
||||
{ return comparesEqual(s1, QStringView(s2)); }
|
||||
friend Qt::strong_ordering compareThreeWay(const QString &s1, const char16_t *s2) noexcept
|
||||
{ return compareThreeWay(s1, QStringView(s2)); }
|
||||
Q_DECLARE_STRONGLY_ORDERED(QString, const char16_t *)
|
||||
|
||||
// QChar <> QString
|
||||
friend inline bool operator==(QChar lhs, const QString &rhs) noexcept
|
||||
{ return rhs.size() == 1 && lhs == rhs.front(); }
|
||||
friend inline bool operator< (QChar lhs, const QString &rhs) noexcept
|
||||
{ return compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; }
|
||||
friend inline bool operator> (QChar lhs, const QString &rhs) noexcept
|
||||
{ return compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; }
|
||||
|
||||
friend inline bool operator!=(QChar lhs, const QString &rhs) noexcept { return !(lhs == rhs); }
|
||||
friend inline bool operator<=(QChar lhs, const QString &rhs) noexcept { return !(lhs > rhs); }
|
||||
friend inline bool operator>=(QChar lhs, const QString &rhs) noexcept { return !(lhs < rhs); }
|
||||
|
||||
friend inline bool operator==(const QString &lhs, QChar rhs) noexcept { return rhs == lhs; }
|
||||
friend inline bool operator!=(const QString &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
|
||||
friend inline bool operator< (const QString &lhs, QChar rhs) noexcept { return rhs > lhs; }
|
||||
friend inline bool operator> (const QString &lhs, QChar rhs) noexcept { return rhs < lhs; }
|
||||
friend inline bool operator<=(const QString &lhs, QChar rhs) noexcept { return !(rhs < lhs); }
|
||||
friend inline bool operator>=(const QString &lhs, QChar rhs) noexcept { return !(rhs > lhs); }
|
||||
friend bool comparesEqual(const QString &lhs, QChar rhs) noexcept
|
||||
{ return lhs.size() == 1 && rhs == lhs.front(); }
|
||||
friend Qt::strong_ordering compareThreeWay(const QString &lhs, QChar rhs) noexcept
|
||||
{
|
||||
const int res = compare_helper(lhs.data(), lhs.size(), &rhs, 1);
|
||||
return Qt::compareThreeWay(res, 0);
|
||||
}
|
||||
Q_DECLARE_STRONGLY_ORDERED(QString, QChar)
|
||||
|
||||
// ASCII compatibility
|
||||
#if defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
|
@ -27,6 +27,7 @@ foreach(test tst_qstring tst_qstring_restricted_ascii tst_qstring_no_cast_from_a
|
||||
${tst_qstring_extra_sources}
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::TestPrivate
|
||||
${tst_qstring_extra_libraries}
|
||||
DEFINES
|
||||
${tst_qstring_extra_defines}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include <private/qglobal_p.h> // for the icu feature test
|
||||
#include <QtTest/private/qcomparisontesthelper_p.h>
|
||||
#include <QTest>
|
||||
#include <QString>
|
||||
#include <QStringBuilder>
|
||||
@ -668,8 +669,11 @@ private slots:
|
||||
void isNan_data();
|
||||
void isNan();
|
||||
void nanAndInf();
|
||||
void comparisonCompiles();
|
||||
void compare_data();
|
||||
void compare();
|
||||
void comparisonMacros_data();
|
||||
void comparisonMacros();
|
||||
void resize();
|
||||
void resizeAfterFromRawData();
|
||||
void resizeAfterReserve();
|
||||
@ -8030,6 +8034,15 @@ void tst_QString::arg_fillChar()
|
||||
QCOMPARE(actual, expected);
|
||||
}
|
||||
|
||||
void tst_QString::comparisonCompiles()
|
||||
{
|
||||
QTestPrivate::testAllComparisonOperatorsCompile<QString>();
|
||||
QTestPrivate::testAllComparisonOperatorsCompile<QString, std::nullptr_t>();
|
||||
QTestPrivate::testAllComparisonOperatorsCompile<QString, QChar>();
|
||||
QTestPrivate::testAllComparisonOperatorsCompile<QString, QLatin1StringView>();
|
||||
QTestPrivate::testAllComparisonOperatorsCompile<QString, const char16_t *>();
|
||||
}
|
||||
|
||||
void tst_QString::compare_data()
|
||||
{
|
||||
QTest::addColumn<QString>("s1");
|
||||
@ -8219,6 +8232,44 @@ void tst_QString::compare()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::comparisonMacros_data()
|
||||
{
|
||||
compare_data();
|
||||
}
|
||||
|
||||
void tst_QString::comparisonMacros()
|
||||
{
|
||||
QFETCH(const QString, s1);
|
||||
QFETCH(const QString, s2);
|
||||
QFETCH(int, csr);
|
||||
|
||||
const Qt::strong_ordering expectedOrdering = [&csr] {
|
||||
if (csr > 0)
|
||||
return Qt::strong_ordering::greater;
|
||||
else if (csr < 0)
|
||||
return Qt::strong_ordering::less;
|
||||
return Qt::strong_ordering::equal;
|
||||
}();
|
||||
|
||||
QT_TEST_ALL_COMPARISON_OPS(s1, s2, 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);
|
||||
}
|
||||
|
||||
if (s2.size() == 1) {
|
||||
const QChar ch = s2.front();
|
||||
QT_TEST_ALL_COMPARISON_OPS(s1, ch, expectedOrdering);
|
||||
}
|
||||
|
||||
if (isLatin(s2)) {
|
||||
QByteArray ba = s2.toLatin1();
|
||||
const QLatin1StringView l1s2{ba};
|
||||
QT_TEST_ALL_COMPARISON_OPS(s1, l1s2, expectedOrdering);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::resize()
|
||||
{
|
||||
QString s;
|
||||
|
Loading…
x
Reference in New Issue
Block a user