QLatin1StringMatcher: add indexIn(QStringView) overload
Drive-by changes, remove a redundant typedef. [ChangeLog][QtCore][QLatin1StringMatcher] Added indexIn(QStringView) overload. Task-number: QTBUG-117054 Change-Id: I5a8426cb0f9d9111f086015902ffe2185a267c86 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Øystein Heskestad <oystein.heskestad@qt.io>
This commit is contained in:
parent
519a47e870
commit
c878a51509
@ -160,6 +160,31 @@ Qt::CaseSensitivity QLatin1StringMatcher::caseSensitivity() const noexcept
|
||||
*/
|
||||
qsizetype QLatin1StringMatcher::indexIn(QLatin1StringView haystack, qsizetype from) const noexcept
|
||||
{
|
||||
return indexIn_helper(haystack, from);
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 6.8
|
||||
\overload
|
||||
|
||||
Searches for the pattern in the given \a haystack starting from index
|
||||
position \a from.
|
||||
|
||||
\sa caseSensitivity(), pattern()
|
||||
*/
|
||||
qsizetype QLatin1StringMatcher::indexIn(QStringView haystack, qsizetype from) const noexcept
|
||||
{
|
||||
return indexIn_helper(haystack, from);
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
template <typename String>
|
||||
qsizetype QLatin1StringMatcher::indexIn_helper(String haystack, qsizetype from) const noexcept
|
||||
{
|
||||
static_assert(QtPrivate::isLatin1OrUtf16View<String>);
|
||||
|
||||
if (m_pattern.isEmpty() && from == haystack.size())
|
||||
return from;
|
||||
if (from < 0) // Historical behavior (see QString::indexOf and co.)
|
||||
@ -167,8 +192,15 @@ qsizetype QLatin1StringMatcher::indexIn(QLatin1StringView haystack, qsizetype fr
|
||||
if (from >= haystack.size())
|
||||
return -1;
|
||||
|
||||
auto begin = haystack.begin() + from;
|
||||
auto end = haystack.end();
|
||||
const auto start = [haystack] {
|
||||
if constexpr (std::is_same_v<String, QStringView>)
|
||||
return haystack.utf16();
|
||||
else
|
||||
return haystack.begin();
|
||||
}();
|
||||
|
||||
auto begin = start + from;
|
||||
auto end = start + haystack.size();
|
||||
auto found = begin;
|
||||
if (m_cs == Qt::CaseSensitive) {
|
||||
found = m_caseSensitiveSearcher(begin, end, m_pattern.begin(), m_pattern.end()).begin;
|
||||
@ -178,7 +210,7 @@ qsizetype QLatin1StringMatcher::indexIn(QLatin1StringView haystack, qsizetype fr
|
||||
const qsizetype bufferSize = std::min(m_pattern.size(), qsizetype(sizeof m_foldBuffer));
|
||||
const QLatin1StringView restNeedle = m_pattern.sliced(bufferSize);
|
||||
const bool needleLongerThanBuffer = restNeedle.size() > 0;
|
||||
QLatin1StringView restHaystack = haystack;
|
||||
String restHaystack = haystack;
|
||||
do {
|
||||
found = m_caseInsensitiveSearcher(found, end, m_foldBuffer, &m_foldBuffer[bufferSize])
|
||||
.begin;
|
||||
@ -189,13 +221,13 @@ qsizetype QLatin1StringMatcher::indexIn(QLatin1StringView haystack, qsizetype fr
|
||||
}
|
||||
restHaystack = haystack.sliced(
|
||||
qMin(haystack.size(),
|
||||
bufferSize + qsizetype(std::distance(haystack.begin(), found))));
|
||||
bufferSize + qsizetype(std::distance(start, found))));
|
||||
if (restHaystack.startsWith(restNeedle, Qt::CaseInsensitive))
|
||||
break;
|
||||
++found;
|
||||
} while (true);
|
||||
}
|
||||
return std::distance(haystack.begin(), found);
|
||||
return std::distance(start, found);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -14,6 +14,10 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtPrivate {
|
||||
template <typename T>
|
||||
constexpr inline bool isLatin1OrUtf16View =
|
||||
std::disjunction_v<std::is_same<T, QLatin1StringView>, std::is_same<T, QStringView>>;
|
||||
|
||||
template<class RandomIt1,
|
||||
class Hash = std::hash<typename std::iterator_traits<RandomIt1>::value_type>,
|
||||
class BinaryPredicate = std::equal_to<>>
|
||||
@ -147,6 +151,7 @@ public:
|
||||
Q_CORE_EXPORT Qt::CaseSensitivity caseSensitivity() const noexcept;
|
||||
|
||||
Q_CORE_EXPORT qsizetype indexIn(QLatin1StringView haystack, qsizetype from = 0) const noexcept;
|
||||
Q_CORE_EXPORT qsizetype indexIn(QStringView haystack, qsizetype from = 0) const noexcept;
|
||||
|
||||
private:
|
||||
void setSearcher() noexcept;
|
||||
@ -164,6 +169,10 @@ private:
|
||||
CaseSensitiveSearcher m_caseSensitiveSearcher;
|
||||
CaseInsensitiveSearcher m_caseInsensitiveSearcher;
|
||||
};
|
||||
|
||||
template <typename String>
|
||||
qsizetype indexIn_helper(String haystack, qsizetype from) const noexcept;
|
||||
|
||||
char m_foldBuffer[256];
|
||||
};
|
||||
|
||||
|
@ -44,6 +44,12 @@ void tst_QLatin1StringMatcher::overloads()
|
||||
QCOMPARE(m.indexIn("Hellohello"_L1), 5);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1), 0);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1, 1), -1);
|
||||
|
||||
QCOMPARE(m.indexIn(u"hello"), 0);
|
||||
QCOMPARE(m.indexIn(u"Hello"), -1);
|
||||
QCOMPARE(m.indexIn(u"Hellohello"), 5);
|
||||
QCOMPARE(m.indexIn(u"helloHello"), 0);
|
||||
QCOMPARE(m.indexIn(u"helloHello", 1), -1);
|
||||
}
|
||||
{
|
||||
QLatin1StringMatcher m("Hello"_L1, Qt::CaseSensitive);
|
||||
@ -53,6 +59,12 @@ void tst_QLatin1StringMatcher::overloads()
|
||||
QCOMPARE(m.indexIn("Hellohello"_L1), 0);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1), 5);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
|
||||
|
||||
QCOMPARE(m.indexIn(u"hello"), -1);
|
||||
QCOMPARE(m.indexIn(u"Hello"), 0);
|
||||
QCOMPARE(m.indexIn(u"Hellohello"), 0);
|
||||
QCOMPARE(m.indexIn(u"helloHello"), 5);
|
||||
QCOMPARE(m.indexIn(u"helloHello", 6), -1);
|
||||
}
|
||||
{
|
||||
QLatin1StringMatcher m("hello"_L1, Qt::CaseInsensitive);
|
||||
@ -63,6 +75,13 @@ void tst_QLatin1StringMatcher::overloads()
|
||||
QCOMPARE(m.indexIn("helloHello"_L1), 0);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
|
||||
|
||||
QCOMPARE(m.indexIn(u"hello"), 0);
|
||||
QCOMPARE(m.indexIn(u"Hello"), 0);
|
||||
QCOMPARE(m.indexIn(u"Hellohello"), 0);
|
||||
QCOMPARE(m.indexIn(u"helloHello"), 0);
|
||||
QCOMPARE(m.indexIn(u"helloHello", 1), 5);
|
||||
QCOMPARE(m.indexIn(u"helloHello", 6), -1);
|
||||
}
|
||||
{
|
||||
QLatin1StringMatcher m("Hello"_L1, Qt::CaseInsensitive);
|
||||
@ -73,6 +92,13 @@ void tst_QLatin1StringMatcher::overloads()
|
||||
QCOMPARE(m.indexIn("helloHello"_L1), 0);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
|
||||
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
|
||||
|
||||
QCOMPARE(m.indexIn(u"hello"), 0);
|
||||
QCOMPARE(m.indexIn(u"Hello"), 0);
|
||||
QCOMPARE(m.indexIn(u"Hellohello"), 0);
|
||||
QCOMPARE(m.indexIn(u"helloHello"), 0);
|
||||
QCOMPARE(m.indexIn(u"helloHello", 1), 5);
|
||||
QCOMPARE(m.indexIn(u"helloHello", 6), -1);
|
||||
}
|
||||
{
|
||||
QLatin1StringMatcher m(hello, Qt::CaseSensitive);
|
||||
@ -81,6 +107,11 @@ void tst_QLatin1StringMatcher::overloads()
|
||||
QCOMPARE(m.indexIn(hello, 1), -1);
|
||||
QCOMPARE(m.indexIn(hello2, 1), hello.size());
|
||||
QCOMPARE(m.indexIn(hello2, 6), -1);
|
||||
|
||||
QCOMPARE(m.indexIn(QString::fromLatin1(hello)), 0);
|
||||
QCOMPARE(m.indexIn(QString::fromLatin1(hello), 1), -1);
|
||||
QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 1), hello.size());
|
||||
QCOMPARE(m.indexIn(QString::fromLatin1(hello2), 6), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,25 +418,35 @@ void tst_QLatin1StringMatcher::haystacksWithMoreThan4GiBWork()
|
||||
QCOMPARE(large.size(), BaseSize + needle.size());
|
||||
qDebug("created dataset in %lld ms", timer.elapsed());
|
||||
|
||||
using MaybeThread = std::thread;
|
||||
{
|
||||
//
|
||||
// WHEN: trying to match an occurrence past the 4GiB mark
|
||||
//
|
||||
qsizetype dynamicResult;
|
||||
auto t = std::thread{ [&] {
|
||||
QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive);
|
||||
dynamicResult = m.indexIn(QLatin1StringView(large));
|
||||
} };
|
||||
t.join();
|
||||
|
||||
//
|
||||
// WHEN: trying to match an occurrence past the 4GiB mark
|
||||
//
|
||||
//
|
||||
// THEN: the result index is not truncated
|
||||
//
|
||||
|
||||
qsizetype dynamicResult;
|
||||
QCOMPARE(dynamicResult, qsizetype(BaseSize));
|
||||
}
|
||||
|
||||
auto t = MaybeThread{ [&] {
|
||||
QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive);
|
||||
dynamicResult = m.indexIn(QLatin1StringView(large));
|
||||
} };
|
||||
t.join();
|
||||
{
|
||||
qsizetype dynamicResult;
|
||||
auto t = std::thread{ [&] {
|
||||
QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive);
|
||||
dynamicResult = m.indexIn(QStringView(QString::fromLatin1(large)));
|
||||
} };
|
||||
t.join();
|
||||
|
||||
//
|
||||
// THEN: the result index is not trucated
|
||||
//
|
||||
QCOMPARE(dynamicResult, qsizetype(BaseSize));
|
||||
}
|
||||
|
||||
QCOMPARE(dynamicResult, qsizetype(BaseSize));
|
||||
#else
|
||||
QSKIP("This test is 64-bit only.");
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user