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
|
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())
|
if (m_pattern.isEmpty() && from == haystack.size())
|
||||||
return from;
|
return from;
|
||||||
if (from < 0) // Historical behavior (see QString::indexOf and co.)
|
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())
|
if (from >= haystack.size())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
auto begin = haystack.begin() + from;
|
const auto start = [haystack] {
|
||||||
auto end = haystack.end();
|
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;
|
auto found = begin;
|
||||||
if (m_cs == Qt::CaseSensitive) {
|
if (m_cs == Qt::CaseSensitive) {
|
||||||
found = m_caseSensitiveSearcher(begin, end, m_pattern.begin(), m_pattern.end()).begin;
|
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 qsizetype bufferSize = std::min(m_pattern.size(), qsizetype(sizeof m_foldBuffer));
|
||||||
const QLatin1StringView restNeedle = m_pattern.sliced(bufferSize);
|
const QLatin1StringView restNeedle = m_pattern.sliced(bufferSize);
|
||||||
const bool needleLongerThanBuffer = restNeedle.size() > 0;
|
const bool needleLongerThanBuffer = restNeedle.size() > 0;
|
||||||
QLatin1StringView restHaystack = haystack;
|
String restHaystack = haystack;
|
||||||
do {
|
do {
|
||||||
found = m_caseInsensitiveSearcher(found, end, m_foldBuffer, &m_foldBuffer[bufferSize])
|
found = m_caseInsensitiveSearcher(found, end, m_foldBuffer, &m_foldBuffer[bufferSize])
|
||||||
.begin;
|
.begin;
|
||||||
@ -189,13 +221,13 @@ qsizetype QLatin1StringMatcher::indexIn(QLatin1StringView haystack, qsizetype fr
|
|||||||
}
|
}
|
||||||
restHaystack = haystack.sliced(
|
restHaystack = haystack.sliced(
|
||||||
qMin(haystack.size(),
|
qMin(haystack.size(),
|
||||||
bufferSize + qsizetype(std::distance(haystack.begin(), found))));
|
bufferSize + qsizetype(std::distance(start, found))));
|
||||||
if (restHaystack.startsWith(restNeedle, Qt::CaseInsensitive))
|
if (restHaystack.startsWith(restNeedle, Qt::CaseInsensitive))
|
||||||
break;
|
break;
|
||||||
++found;
|
++found;
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
return std::distance(haystack.begin(), found);
|
return std::distance(start, found);
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
namespace QtPrivate {
|
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,
|
template<class RandomIt1,
|
||||||
class Hash = std::hash<typename std::iterator_traits<RandomIt1>::value_type>,
|
class Hash = std::hash<typename std::iterator_traits<RandomIt1>::value_type>,
|
||||||
class BinaryPredicate = std::equal_to<>>
|
class BinaryPredicate = std::equal_to<>>
|
||||||
@ -147,6 +151,7 @@ public:
|
|||||||
Q_CORE_EXPORT Qt::CaseSensitivity caseSensitivity() const noexcept;
|
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(QLatin1StringView haystack, qsizetype from = 0) const noexcept;
|
||||||
|
Q_CORE_EXPORT qsizetype indexIn(QStringView haystack, qsizetype from = 0) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setSearcher() noexcept;
|
void setSearcher() noexcept;
|
||||||
@ -164,6 +169,10 @@ private:
|
|||||||
CaseSensitiveSearcher m_caseSensitiveSearcher;
|
CaseSensitiveSearcher m_caseSensitiveSearcher;
|
||||||
CaseInsensitiveSearcher m_caseInsensitiveSearcher;
|
CaseInsensitiveSearcher m_caseInsensitiveSearcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename String>
|
||||||
|
qsizetype indexIn_helper(String haystack, qsizetype from) const noexcept;
|
||||||
|
|
||||||
char m_foldBuffer[256];
|
char m_foldBuffer[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,6 +44,12 @@ void tst_QLatin1StringMatcher::overloads()
|
|||||||
QCOMPARE(m.indexIn("Hellohello"_L1), 5);
|
QCOMPARE(m.indexIn("Hellohello"_L1), 5);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1), 0);
|
QCOMPARE(m.indexIn("helloHello"_L1), 0);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1, 1), -1);
|
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);
|
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), 0);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1), 5);
|
QCOMPARE(m.indexIn("helloHello"_L1), 5);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
|
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);
|
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), 0);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
|
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
|
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);
|
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), 0);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
|
QCOMPARE(m.indexIn("helloHello"_L1, 1), 5);
|
||||||
QCOMPARE(m.indexIn("helloHello"_L1, 6), -1);
|
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);
|
QLatin1StringMatcher m(hello, Qt::CaseSensitive);
|
||||||
@ -81,6 +107,11 @@ void tst_QLatin1StringMatcher::overloads()
|
|||||||
QCOMPARE(m.indexIn(hello, 1), -1);
|
QCOMPARE(m.indexIn(hello, 1), -1);
|
||||||
QCOMPARE(m.indexIn(hello2, 1), hello.size());
|
QCOMPARE(m.indexIn(hello2, 1), hello.size());
|
||||||
QCOMPARE(m.indexIn(hello2, 6), -1);
|
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());
|
QCOMPARE(large.size(), BaseSize + needle.size());
|
||||||
qDebug("created dataset in %lld ms", timer.elapsed());
|
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);
|
qsizetype dynamicResult;
|
||||||
dynamicResult = m.indexIn(QLatin1StringView(large));
|
auto t = std::thread{ [&] {
|
||||||
} };
|
QLatin1StringMatcher m(QLatin1StringView(needle), Qt::CaseSensitive);
|
||||||
t.join();
|
dynamicResult = m.indexIn(QStringView(QString::fromLatin1(large)));
|
||||||
|
} };
|
||||||
|
t.join();
|
||||||
|
|
||||||
//
|
QCOMPARE(dynamicResult, qsizetype(BaseSize));
|
||||||
// THEN: the result index is not trucated
|
}
|
||||||
//
|
|
||||||
|
|
||||||
QCOMPARE(dynamicResult, qsizetype(BaseSize));
|
|
||||||
#else
|
#else
|
||||||
QSKIP("This test is 64-bit only.");
|
QSKIP("This test is 64-bit only.");
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user