QStaticLatin1StringMatcher: add indexIn(QStringView)

... mirroring the same change in QLatin1StringMatcher.

Task-number: QTBUG-117054
Change-Id: I8d1f4ed01ee75a51e3d99a165dbb35ae7dae5886
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Ahmad Samir 2023-09-17 17:16:33 +03:00
parent ec88e63f2a
commit 9a61bc5dfc
3 changed files with 145 additions and 3 deletions

View File

@ -109,13 +109,30 @@ public:
} }
constexpr qsizetype indexIn(QLatin1StringView haystack, qsizetype from = 0) const noexcept constexpr qsizetype indexIn(QLatin1StringView haystack, qsizetype from = 0) const noexcept
{ return indexIn_helper(haystack, from); }
constexpr qsizetype indexIn(QStringView haystack, qsizetype from = 0) const noexcept
{ return indexIn_helper(haystack, from); }
private:
template <typename String>
constexpr qsizetype indexIn_helper(String haystack, qsizetype from = 0) const noexcept
{ {
static_assert(QtPrivate::isLatin1OrUtf16View<String>);
if (from >= haystack.size()) if (from >= haystack.size())
return -1; return -1;
const char *begin = haystack.begin() + from;
const char *end = haystack.end(); const auto start = [haystack]() constexpr {
if constexpr (std::is_same_v<String, QStringView>)
return haystack.utf16();
else
return haystack.begin();
}();
const auto begin = start + from;
const auto end = start + haystack.size();
const auto r = m_searcher(begin, end, m_pattern.begin(), m_pattern.end()); const auto r = m_searcher(begin, end, m_pattern.begin(), m_pattern.end());
return r.begin == end ? -1 : std::distance(haystack.begin(), r.begin); return r.begin == end ? -1 : std::distance(start, r.begin);
} }
}; };

View File

@ -44,6 +44,7 @@
/*! /*!
\fn template<Qt::CaseSensitivity CS, size_t N> constexpr qsizetype QStaticLatin1StringMatcher<CS, N>::indexIn(QLatin1StringView haystack, qsizetype from) const \fn template<Qt::CaseSensitivity CS, size_t N> constexpr qsizetype QStaticLatin1StringMatcher<CS, N>::indexIn(QLatin1StringView haystack, qsizetype from) const
\fn template<Qt::CaseSensitivity CS, size_t N> constexpr qsizetype QStaticLatin1StringMatcher<CS, N>::indexIn(QStringView haystack, qsizetype from) const
Searches the QLatin1StringView \a haystack, from byte position \a from Searches the QLatin1StringView \a haystack, from byte position \a from
(default 0, i.e. from the first byte), for QLatin1StringView pattern() (default 0, i.e. from the first byte), for QLatin1StringView pattern()

View File

@ -25,6 +25,7 @@ class tst_QLatin1StringMatcher : public QObject
private slots: private slots:
void overloads(); void overloads();
void staticOverloads(); void staticOverloads();
void staticOverloads_QStringViewHaystack();
void interface(); void interface();
void indexIn(); void indexIn();
void haystacksWithMoreThan4GiBWork(); void haystacksWithMoreThan4GiBWork();
@ -237,6 +238,129 @@ void tst_QLatin1StringMatcher::staticOverloads()
#endif #endif
} }
void tst_QLatin1StringMatcher::staticOverloads_QStringViewHaystack()
{
#ifdef QT_STATIC_BOYER_MOORE_NOT_SUPPORTED
QSKIP("Test is only valid on an OS that supports static latin1 string matcher");
#else
constexpr QStringView hello = u"hello";
QString hello2B = QStringView(hello).toString().repeated(2);
hello2B += QStringView(u"🍉");
QStringView hello2(hello2B);
{
static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("hel");
QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), -1);
QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 5);
QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1);
QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0);
QCOMPARE(m.indexIn(hello), 0);
QCOMPARE(m.indexIn(hello, 1), -1); // from is 1
QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2
QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3
QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
static_assert(m.indexIn(QStringView(u"hello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"Hello🍉")) == -1);
static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 5);
static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"he🍉")) == -1);
static_assert(m.indexIn(QStringView(u"hel🍉")) == 0);
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6
}
{
static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("Hel");
QCOMPARE(m.indexIn(QStringView(u"hello🍉")), -1);
QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 5);
QCOMPARE(m.indexIn(QStringView(u"helloHello🍉"), 6), -1);
QCOMPARE(m.indexIn(QStringView(u"He🍉")), -1);
QCOMPARE(m.indexIn(QStringView(u"Hel🍉")), 0);
QCOMPARE(m.indexIn(hello), -1);
QCOMPARE(m.indexIn(hello2, 2), -1); // from is 2
QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
static_assert(m.indexIn(QStringView(u"hello🍉")) == -1);
static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 5);
static_assert(m.indexIn(QStringView(u"helloHello🍉"), 6) == -1);
static_assert(m.indexIn(QStringView(u"He🍉")) == -1);
static_assert(m.indexIn(QStringView(u"Hel🍉")) == 0);
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == -1); // from is 2
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6
}
{
static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("hel");
QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1);
QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0);
QCOMPARE(m.indexIn(hello), 0);
QCOMPARE(m.indexIn(hello, 1), -1);
QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2
QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3
QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
static_assert(m.indexIn(QStringView(u"hello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"he🍉")) == -1);
static_assert(m.indexIn(QStringView(u"hel🍉")) == 0);
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6
}
{
static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("Hel");
QCOMPARE(m.indexIn(QStringView(u"hello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"Hello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"Hellohello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"helloHello🍉")), 0);
QCOMPARE(m.indexIn(QStringView(u"he🍉")), -1);
QCOMPARE(m.indexIn(QStringView(u"hel🍉")), 0);
QCOMPARE(m.indexIn(hello), 0);
QCOMPARE(m.indexIn(hello, 1), -1);
QCOMPARE(m.indexIn(hello2, 2), hello.size()); // from is 2
QCOMPARE(m.indexIn(hello2, 3), hello.size()); // from is 3
QCOMPARE(m.indexIn(hello2, 6), -1); // from is 6
static_assert(m.indexIn(QStringView(u"hello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"Hello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"Hellohello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"helloHello🍉")) == 0);
static_assert(m.indexIn(QStringView(u"he🍉")) == -1);
static_assert(m.indexIn(QStringView(u"hel🍉")) == 0);
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 2) == 5); // from is 2
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 3) == 5); // from is 3
static_assert(m.indexIn(QStringView(u"hellohello🍉"), 6) == -1); // from is 6
}
{
static constexpr auto m = qMakeStaticCaseInsensitiveLatin1StringMatcher("b\xF8");
QCOMPARE(m.indexIn(QStringView(u"B\xD8")), 0);
QCOMPARE(m.indexIn(QStringView(u"B\xF8")), 0);
QCOMPARE(m.indexIn(QStringView(u"b\xD8")), 0);
QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0);
QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0);
QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1);
QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3);
}
{
static constexpr auto m = qMakeStaticCaseSensitiveLatin1StringMatcher("b\xF8");
QCOMPARE(m.indexIn(QStringView(u"B\xD8")), -1);
QCOMPARE(m.indexIn(QStringView(u"B\xF8")), -1);
QCOMPARE(m.indexIn(QStringView(u"b\xD8")), -1);
QCOMPARE(m.indexIn(QStringView(u"b\xF8")), 0);
QCOMPARE(m.indexIn(QStringView(u"b\xF8lle")), 0);
QCOMPARE(m.indexIn(QStringView(u"m\xF8lle")), -1);
QCOMPARE(m.indexIn(QStringView(u"Si b\xF8")), 3);
}
#endif
}
void tst_QLatin1StringMatcher::interface() void tst_QLatin1StringMatcher::interface()
{ {
QLatin1StringView needle = "abc123"_L1; QLatin1StringView needle = "abc123"_L1;