diff options
-rw-r--r-- | src/corelib/text/qstring.cpp | 19 | ||||
-rw-r--r-- | src/corelib/text/qstringalgorithms.h | 3 | ||||
-rw-r--r-- | src/corelib/text/qstringview.cpp | 30 | ||||
-rw-r--r-- | src/corelib/text/qstringview.h | 5 | ||||
-rw-r--r-- | tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp | 51 |
5 files changed, 97 insertions, 11 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 12759c4a5b..cda1c380bd 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -151,8 +151,6 @@ static inline qsizetype qLastIndexOf(Haystack haystack, QChar needle, qsizetype template <> inline qsizetype qLastIndexOf(QString haystack, QChar needle, qsizetype from, Qt::CaseSensitivity cs) noexcept = delete; // unwanted, would detach -static inline qsizetype qt_string_count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs); -static inline qsizetype qt_string_count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs); static inline bool qt_starts_with(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs); static inline bool qt_starts_with(QStringView haystack, QLatin1String needle, Qt::CaseSensitivity cs); @@ -4021,7 +4019,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after) int QString::count(const QString &str, Qt::CaseSensitivity cs) const { // ### Qt6: qsizetype - return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); + return int(QtPrivate::count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); } /*! @@ -4038,7 +4036,7 @@ int QString::count(const QString &str, Qt::CaseSensitivity cs) const int QString::count(QChar ch, Qt::CaseSensitivity cs) const { // ### Qt6: qsizetype - return int(qt_string_count(QStringView(unicode(), size()), ch, cs)); + return int(QtPrivate::count(QStringView(unicode(), size()), ch, cs)); } /*! @@ -4055,7 +4053,7 @@ int QString::count(QChar ch, Qt::CaseSensitivity cs) const int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const { // ### Qt6: qsizetype - return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); + return int(QtPrivate::count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); } #if QT_STRINGVIEW_LEVEL < 2 @@ -10932,7 +10930,7 @@ int QStringRef::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity int QStringRef::count(const QString &str, Qt::CaseSensitivity cs) const { // ### Qt6: qsizetype - return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); + return int(QtPrivate::count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); } /*! @@ -10950,7 +10948,7 @@ int QStringRef::count(const QString &str, Qt::CaseSensitivity cs) const int QStringRef::count(QChar ch, Qt::CaseSensitivity cs) const { // ### Qt6: qsizetype - return int(qt_string_count(QStringView(unicode(), size()), ch, cs)); + return int(QtPrivate::count(QStringView(unicode(), size()), ch, cs)); } /*! @@ -10968,7 +10966,7 @@ int QStringRef::count(QChar ch, Qt::CaseSensitivity cs) const int QStringRef::count(const QStringRef &str, Qt::CaseSensitivity cs) const { // ### Qt6: qsizetype - return int(qt_string_count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); + return int(QtPrivate::count(QStringView(unicode(), size()), QStringView(str.unicode(), str.size()), cs)); } /*! @@ -11221,7 +11219,7 @@ bool QStringRef::endsWith(const QStringRef &str, Qt::CaseSensitivity cs) const \sa indexOf(), count() */ -static inline qsizetype qt_string_count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs) +qsizetype QtPrivate::count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs) noexcept { qsizetype num = 0; qsizetype i = -1; @@ -11236,8 +11234,7 @@ static inline qsizetype qt_string_count(QStringView haystack, QStringView needle return num; } -static inline qsizetype qt_string_count(QStringView haystack, QChar ch, - Qt::CaseSensitivity cs) +qsizetype QtPrivate::count(QStringView haystack, QChar ch, Qt::CaseSensitivity cs) noexcept { qsizetype num = 0; if (cs == Qt::CaseSensitive) { diff --git a/src/corelib/text/qstringalgorithms.h b/src/corelib/text/qstringalgorithms.h index 86bacdccad..f1aa052eac 100644 --- a/src/corelib/text/qstringalgorithms.h +++ b/src/corelib/text/qstringalgorithms.h @@ -88,6 +88,9 @@ Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QLati Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QStringView trimmed(QStringView s) noexcept; Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QLatin1String trimmed(QLatin1String s) noexcept; +Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept; +Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept; + Q_REQUIRED_RESULT Q_CORE_EXPORT QByteArray convertToLatin1(QStringView str); Q_REQUIRED_RESULT Q_CORE_EXPORT QByteArray convertToUtf8(QStringView str); Q_REQUIRED_RESULT Q_CORE_EXPORT QByteArray convertToLocal8Bit(QStringView str); diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp index 8f87943204..abb7015b68 100644 --- a/src/corelib/text/qstringview.cpp +++ b/src/corelib/text/qstringview.cpp @@ -914,6 +914,36 @@ QT_BEGIN_NAMESPACE */ /*! + \fn qsizetype QStringView::count(QChar ch, Qt::CaseSensitivity cs) const noexcept + + \since 6.0 + \overload count() + + Returns the number of occurrences of the character \a ch in the + string reference. + + If \a cs is Qt::CaseSensitive (default), the search is + case sensitive; otherwise the search is case insensitive. + + \sa QString::count(), contains(), indexOf() +*/ + +/*! + \fn qsizetype QStringView::count(QStringView str, Qt::CaseSensitivity cs) const noexcept + + \since 6.0 + \overload count() + + Returns the number of (potentially overlapping) occurrences of the + string reference \a str in this string reference. + + If \a cs is Qt::CaseSensitive (default), the search is + case sensitive; otherwise the search is case insensitive. + + \sa QString::count(), contains(), indexOf() +*/ + +/*! \fn qint64 QStringView::toLongLong(bool *ok, int base) const Returns the string converted to a \c{long long} using base \a diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h index 2b7863e156..e2e1abb62d 100644 --- a/src/corelib/text/qstringview.h +++ b/src/corelib/text/qstringview.h @@ -309,6 +309,11 @@ public: { return indexOf(s, 0, cs) != qsizetype(-1); } Q_REQUIRED_RESULT inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept; + Q_REQUIRED_RESULT qsizetype count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept + { return QtPrivate::count(*this, c, cs); } + Q_REQUIRED_RESULT qsizetype count(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept + { return QtPrivate::count(*this, s, cs); } + Q_REQUIRED_RESULT qsizetype lastIndexOf(QChar c, qsizetype from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept { return QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs); } Q_REQUIRED_RESULT qsizetype lastIndexOf(QStringView s, qsizetype from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept diff --git a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp index 0fdad63b24..a55f2f13eb 100644 --- a/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp +++ b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp @@ -603,6 +603,20 @@ private Q_SLOTS: void toNumber_QByteArray_data() { toNumber_data(); } void toNumber_QByteArray() { toNumber_impl<QByteArray>(); } +private: + void count_data(); + template <typename String> void count_impl(); + +private Q_SLOTS: + void count_QString_data() { count_data(); } + void count_QString() { count_impl<QString>(); } + void count_QStringRef_data() { count_data(); } + void count_QStringRef() { count_impl<QStringRef>(); } + void count_QStringView_data() { count_data(); } + void count_QStringView() { count_impl<QStringView>(); } + void count_QByteArray_data() { count_data(); } + void count_QByteArray() { count_impl<QByteArray>(); } + // // UTF-16-only checks: // @@ -1713,6 +1727,43 @@ void tst_QStringApiSymmetry::toNumber_impl() } } + +void tst_QStringApiSymmetry::count_data() +{ + QTest::addColumn<QString>("data"); + QTest::addColumn<QString>("needle"); + QTest::addColumn<qsizetype>("result"); + + QTest::addRow("xxx") << QString::fromUtf8("xxx") << QString::fromUtf8("x") << qsizetype(3); + QTest::addRow("xyzaaaxyz") << QString::fromUtf8("xyzaaaxyz") << QString::fromUtf8("xyz") << qsizetype(2); +} + +template <typename String> +void tst_QStringApiSymmetry::count_impl() +{ + QFETCH(const QString, data); + QFETCH(const QString, needle); + QFETCH(qsizetype, result); + + const auto utf8 = data.toUtf8(); + const auto l1s = data.toLatin1(); + const auto l1 = l1s.isNull() ? QLatin1String() : QLatin1String(l1s); + + const auto ref = data.isNull() ? QStringRef() : QStringRef(&data); + const auto s = make<String>(ref, l1, utf8); + + const auto nutf8 = needle.toUtf8(); + const auto nl1s = needle.toLatin1(); + const auto nl1 = nl1s.isNull() ? QLatin1String() : QLatin1String(l1s); + + const auto nref = needle.isNull() ? QStringRef() : QStringRef(&needle); + const auto ns = make<String>(nref, nl1, nutf8); + + QCOMPARE(s.count(ns), result); + if (ns.length() == 1) + QCOMPARE(s.count(ns.data()[0]), result); +} + // // // UTF-16-only checks: |