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
{ 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())
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());
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(QStringView haystack, qsizetype from) const
Searches the QLatin1StringView \a haystack, from byte position \a from
(default 0, i.e. from the first byte), for QLatin1StringView pattern()

View File

@ -25,6 +25,7 @@ class tst_QLatin1StringMatcher : public QObject
private slots:
void overloads();
void staticOverloads();
void staticOverloads_QStringViewHaystack();
void interface();
void indexIn();
void haystacksWithMoreThan4GiBWork();
@ -237,6 +238,129 @@ void tst_QLatin1StringMatcher::staticOverloads()
#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()
{
QLatin1StringView needle = "abc123"_L1;