Add QLatin1String::count(needle)
[ChangeLog][QtCore][QLatin1String] Added QLatin1String::count(needle). Task-number: QTBUG-98433 Change-Id: I31c9fdf14fd81500722ff9f5998eadf0e6cedc5c Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
567c31e8ee
commit
30d28810ee
@ -9490,6 +9490,22 @@ QString &QString::setRawData(const QChar *unicode, qsizetype size)
|
|||||||
\overload
|
\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
|
\fn QLatin1String::const_iterator QLatin1String::begin() const
|
||||||
\since 5.10
|
\since 5.10
|
||||||
@ -10380,6 +10396,75 @@ qsizetype QtPrivate::count(QStringView haystack, QChar ch, Qt::CaseSensitivity c
|
|||||||
return num;
|
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<uchar> 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 <typename Haystack, typename Needle>
|
template <typename Haystack, typename Needle>
|
||||||
bool qt_starts_with_impl(Haystack haystack, Needle needle, Qt::CaseSensitivity cs) noexcept
|
bool qt_starts_with_impl(Haystack haystack, Needle needle, Qt::CaseSensitivity cs) noexcept
|
||||||
{
|
{
|
||||||
|
@ -177,6 +177,13 @@ public:
|
|||||||
[[nodiscard]] qsizetype lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
|
[[nodiscard]] qsizetype lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
|
||||||
{ return QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs); }
|
{ return QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs); }
|
||||||
|
|
||||||
|
[[nodiscard]] qsizetype count(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
|
||||||
|
{ return QtPrivate::count(*this, str, cs); }
|
||||||
|
[[nodiscard]] qsizetype count(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
|
||||||
|
{ return QtPrivate::count(*this, str, cs); }
|
||||||
|
[[nodiscard]] qsizetype count(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
|
||||||
|
{ return QtPrivate::count(*this, ch, cs); }
|
||||||
|
|
||||||
[[nodiscard]] short toShort(bool *ok = nullptr, int base = 10) const
|
[[nodiscard]] short toShort(bool *ok = nullptr, int base = 10) const
|
||||||
{ return QtPrivate::toIntegral<short>(QByteArrayView(*this), ok, base); }
|
{ return QtPrivate::toIntegral<short>(QByteArrayView(*this), ok, base); }
|
||||||
[[nodiscard]] ushort toUShort(bool *ok = nullptr, int base = 10) const
|
[[nodiscard]] ushort toUShort(bool *ok = nullptr, int base = 10) const
|
||||||
|
@ -123,6 +123,9 @@ namespace QtPrivate {
|
|||||||
|
|
||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QStringView haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QLatin1String haystack, QLatin1String needle, Qt::CaseSensitivity cs = Qt::CaseSensitive);
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QLatin1String haystack, QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive);
|
||||||
|
[[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QLatin1String haystack, QChar needle, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
|
||||||
|
|
||||||
#if QT_CONFIG(regularexpression)
|
#if QT_CONFIG(regularexpression)
|
||||||
[[nodiscard]] Q_CORE_EXPORT qsizetype indexOf(QStringView haystack,
|
[[nodiscard]] Q_CORE_EXPORT qsizetype indexOf(QStringView haystack,
|
||||||
|
@ -55,6 +55,7 @@ private Q_SLOTS:
|
|||||||
void iterators();
|
void iterators();
|
||||||
void relationalOperators_data();
|
void relationalOperators_data();
|
||||||
void relationalOperators();
|
void relationalOperators();
|
||||||
|
void count();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_QLatin1String::constExpr()
|
void tst_QLatin1String::constExpr()
|
||||||
@ -398,6 +399,36 @@ void tst_QLatin1String::relationalOperators()
|
|||||||
#undef CHECK
|
#undef CHECK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QLatin1String::count()
|
||||||
|
{
|
||||||
|
QLatin1String a("ABCDEFGHIEfGEFG");
|
||||||
|
QCOMPARE(a.size(), 15);
|
||||||
|
QCOMPARE(a.count('A'), 1);
|
||||||
|
QCOMPARE(a.count('Z'), 0);
|
||||||
|
QCOMPARE(a.count('E'), 3);
|
||||||
|
QCOMPARE(a.count('F'), 2);
|
||||||
|
QCOMPARE(a.count('F', Qt::CaseInsensitive), 3);
|
||||||
|
QCOMPARE(a.count(QLatin1String("FG")), 2);
|
||||||
|
QCOMPARE(a.count(QLatin1String("FG"), Qt::CaseInsensitive), 3);
|
||||||
|
QCOMPARE(a.count(QLatin1String(), Qt::CaseInsensitive), 16);
|
||||||
|
QCOMPARE(a.count(QLatin1String(""), Qt::CaseInsensitive), 16);
|
||||||
|
|
||||||
|
QLatin1String nullStr;
|
||||||
|
QCOMPARE(nullStr.count('A'), 0);
|
||||||
|
QCOMPARE(nullStr.count(QLatin1String("AB")), 0);
|
||||||
|
QCOMPARE(nullStr.count(QLatin1String()), 1);
|
||||||
|
QCOMPARE(nullStr.count(QLatin1String("")), 1);
|
||||||
|
|
||||||
|
QLatin1String emptyStr("");
|
||||||
|
QCOMPARE(emptyStr.count('A'), 0);
|
||||||
|
QCOMPARE(emptyStr.count(QLatin1String("AB")), 0);
|
||||||
|
QCOMPARE(emptyStr.count(QLatin1String()), 1);
|
||||||
|
QCOMPARE(emptyStr.count(QLatin1String("")), 1);
|
||||||
|
|
||||||
|
using namespace Qt::Literals::StringLiterals;
|
||||||
|
QCOMPARE("a\0b"_L1.count(QChar::SpecialCharacter::LineSeparator), 0);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(tst_QLatin1String)
|
QTEST_APPLESS_MAIN(tst_QLatin1String)
|
||||||
|
|
||||||
#include "tst_qlatin1string.moc"
|
#include "tst_qlatin1string.moc"
|
||||||
|
@ -748,6 +748,19 @@ private Q_SLOTS:
|
|||||||
void count_QStringView_char16_t_data() { count_data(); }
|
void count_QStringView_char16_t_data() { count_data(); }
|
||||||
void count_QStringView_char16_t() { count_impl<QStringView, char16_t>(); }
|
void count_QStringView_char16_t() { count_impl<QStringView, char16_t>(); }
|
||||||
|
|
||||||
|
void count_QLatin1String_QString_data() { count_data(); }
|
||||||
|
void count_QLatin1String_QString() { count_impl<QLatin1String, QString>(); }
|
||||||
|
void count_QLatin1String_QLatin1String_data() { count_data(); }
|
||||||
|
void count_QLatin1String_QLatin1String() { count_impl<QLatin1String, QLatin1String>(); }
|
||||||
|
void count_QLatin1String_QStringView_data() { count_data(); }
|
||||||
|
void count_QLatin1String_QStringView() { count_impl<QLatin1String, QStringView>(); }
|
||||||
|
void count_QLatin1String_QChar_data() { count_data(); }
|
||||||
|
void count_QLatin1String_QChar() { count_impl<QLatin1String, QChar>(); }
|
||||||
|
void count_QLatin1String_char16_t_data() { count_data(); }
|
||||||
|
void count_QLatin1String_char16_t() { count_impl<QLatin1String, char16_t>(); }
|
||||||
|
void count_QLatin1String_QLatin1Char_data() { count_data(); }
|
||||||
|
void count_QLatin1String_QLatin1Char() { count_impl<QLatin1String, QLatin1Char>(); }
|
||||||
|
|
||||||
//
|
//
|
||||||
// UTF-16-only checks:
|
// UTF-16-only checks:
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user