From 30d28810ee73052338e478a5472933c7b9c7d725 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Wed, 2 Mar 2022 09:30:34 +0100 Subject: Add QLatin1String::count(needle) [ChangeLog][QtCore][QLatin1String] Added QLatin1String::count(needle). Task-number: QTBUG-98433 Change-Id: I31c9fdf14fd81500722ff9f5998eadf0e6cedc5c Reviewed-by: Marc Mutz --- src/corelib/text/qstring.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'src/corelib/text/qstring.cpp') diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 0375d68203..3aa86c49a9 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -9490,6 +9490,22 @@ QString &QString::setRawData(const QChar *unicode, qsizetype size) \overload */ +/*! + \fn qsizetype QLatin1String::count(QStringView str, Qt::CaseSensitivity cs) const + \fn qsizetype QLatin1String::count(QLatin1String l1, Qt::CaseSensitivity cs) const + \fn qsizetype QLatin1String::count(QChar ch, Qt::CaseSensitivity cs) const + \since 6.4 + + Returns the number of (potentially overlapping) occurrences of the + string-view \a str, Latin-1 string \a l1, or character \a ch, + respectively, in this Latin-1 string. + + If \a cs is Qt::CaseSensitive (default), the search is + case sensitive; otherwise the search is case insensitive. + + \sa contains(), indexOf() +*/ + /*! \fn QLatin1String::const_iterator QLatin1String::begin() const \since 5.10 @@ -10380,6 +10396,75 @@ qsizetype QtPrivate::count(QStringView haystack, QChar ch, Qt::CaseSensitivity c return num; } +qsizetype QtPrivate::count(QLatin1String haystack, QLatin1String needle, Qt::CaseSensitivity cs) +{ + qsizetype num = 0; + qsizetype i = -1; + + // TODO: use Boyer-Moore searcher for case-insensitive search too + // when QTBUG-100236 is done + if (cs == Qt::CaseSensitive) { + QByteArrayMatcher matcher(needle); + while ((i = matcher.indexIn(haystack, i + 1)) != -1) + ++num; + } else { + while ((i = QtPrivate::findString(haystack, i + 1, needle, cs)) != -1) + ++num; + } + return num; +} + +qsizetype QtPrivate::count(QLatin1String haystack, QStringView needle, Qt::CaseSensitivity cs) +{ + if (haystack.size() < needle.size()) + return 0; + + if (!QtPrivate::isLatin1(needle)) // won't find non-L1 UTF-16 needles in a L1 haystack! + return 0; + + qsizetype num = 0; + qsizetype i = -1; + + // TODO: use Boyer-Moore searcher for case-insensitive search too + // when QTBUG-100236 is done + if (cs == Qt::CaseSensitive) { + QVarLengthArray s(needle.size()); + qt_to_latin1_unchecked(s.data(), needle.utf16(), needle.size()); + + QByteArrayMatcher matcher(s); + while ((i = matcher.indexIn(haystack, i + 1)) != -1) + ++num; + } else { + while ((i = QtPrivate::findString(haystack, i + 1, needle, cs)) != -1) + ++num; + } + return num; +} + +qsizetype QtPrivate::count(QLatin1String haystack, QChar needle, Qt::CaseSensitivity cs) noexcept +{ + // non-L1 needles cannot possibly match in L1-only haystacks + if (needle.unicode() > 0xff) + return 0; + + qsizetype num = 0; + if (cs == Qt::CaseSensitive) { + const char needleL1 = needle.toLatin1(); + for (char c : haystack) { + if (c == needleL1) + ++num; + } + } else { + auto toLower = [](char ch) { return latin1Lower[uchar(ch)]; }; + const uchar ch = toLower(needle.toLatin1()); + for (char c : haystack) { + if (toLower(c) == ch) + ++num; + } + } + return num; +} + template bool qt_starts_with_impl(Haystack haystack, Needle needle, Qt::CaseSensitivity cs) noexcept { -- cgit v1.2.3