Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qlatin1stringmatcher.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include <limits.h>
6
8
46 : m_pattern(),
47 m_cs(Qt::CaseSensitive),
48 m_caseSensitiveSearcher(m_pattern.data(), m_pattern.data())
49{
50}
51
59 Qt::CaseSensitivity cs) noexcept
60 : m_pattern(pattern), m_cs(cs)
61{
62 setSearcher();
63}
64
69{
70 freeSearcher();
71}
72
76void QLatin1StringMatcher::setSearcher() noexcept
77{
78 if (m_cs == Qt::CaseSensitive) {
79 new (&m_caseSensitiveSearcher) CaseSensitiveSearcher(m_pattern.data(), m_pattern.end());
80 } else {
82 qsizetype bufferSize = std::min(m_pattern.size(), qsizetype(sizeof m_foldBuffer));
83 for (qsizetype i = 0; i < bufferSize; ++i)
84 m_foldBuffer[i] = static_cast<char>(foldCase(m_pattern[i].toLatin1()));
85
87 CaseInsensitiveSearcher(m_foldBuffer, &m_foldBuffer[bufferSize]);
88 }
89}
90
94void QLatin1StringMatcher::freeSearcher() noexcept
95{
96 if (m_cs == Qt::CaseSensitive)
97 m_caseSensitiveSearcher.~CaseSensitiveSearcher();
98 else
99 m_caseInsensitiveSearcher.~CaseInsensitiveSearcher();
100}
101
111{
112 if (m_pattern.latin1() == pattern.latin1() && m_pattern.size() == pattern.size())
113 return; // Same address and size
114
115 freeSearcher();
116 m_pattern = pattern;
117 setSearcher();
118}
119
126{
127 return m_pattern;
128}
129
136{
137 if (m_cs == cs)
138 return;
139
140 freeSearcher();
141 m_cs = cs;
142 setSearcher();
143}
144
151{
152 return m_cs;
153}
154
162{
163 return indexIn_helper(haystack, from);
164}
165
176{
177 return indexIn_helper(haystack, from);
178}
179
183template <typename String>
184qsizetype QLatin1StringMatcher::indexIn_helper(String haystack, qsizetype from) const noexcept
185{
186 static_assert(QtPrivate::isLatin1OrUtf16View<String>);
187
188 if (m_pattern.isEmpty() && from == haystack.size())
189 return from;
190 if (from < 0) // Historical behavior (see QString::indexOf and co.)
191 from += haystack.size();
192 if (from >= haystack.size())
193 return -1;
194
195 const auto start = [haystack] {
196 if constexpr (std::is_same_v<String, QStringView>)
197 return haystack.utf16();
198 else
199 return haystack.begin();
200 }();
201
202 auto begin = start + from;
203 auto end = start + haystack.size();
204 auto found = begin;
205 if (m_cs == Qt::CaseSensitive) {
206 found = m_caseSensitiveSearcher(begin, end, m_pattern.begin(), m_pattern.end()).begin;
207 if (found == end)
208 return -1;
209 } else {
210 const qsizetype bufferSize = std::min(m_pattern.size(), qsizetype(sizeof m_foldBuffer));
211 const QLatin1StringView restNeedle = m_pattern.sliced(bufferSize);
212 const bool needleLongerThanBuffer = restNeedle.size() > 0;
213 String restHaystack = haystack;
214 do {
215 found = m_caseInsensitiveSearcher(found, end, m_foldBuffer, &m_foldBuffer[bufferSize])
216 .begin;
217 if (found == end) {
218 return -1;
219 } else if (!needleLongerThanBuffer) {
220 break;
221 }
222 restHaystack = haystack.sliced(
223 qMin(haystack.size(),
224 bufferSize + qsizetype(std::distance(start, found))));
225 if (restHaystack.startsWith(restNeedle, Qt::CaseInsensitive))
226 break;
227 ++found;
228 } while (true);
229 }
230 return std::distance(start, found);
231}
232
Q_CORE_EXPORT qsizetype indexIn(QLatin1StringView haystack, qsizetype from=0) const noexcept
Searches for the pattern in the given haystack starting from from.
Q_CORE_EXPORT Qt::CaseSensitivity caseSensitivity() const noexcept
Returns the case sensitivity the matcher uses.
Q_CORE_EXPORT void setPattern(QLatin1StringView pattern) noexcept
Sets the pattern to search for.
Q_CORE_EXPORT ~QLatin1StringMatcher() noexcept
Destroys the Latin-1 string matcher.
CaseInsensitiveSearcher m_caseInsensitiveSearcher
Q_CORE_EXPORT QLatin1StringView pattern() const noexcept
Returns the Latin-1 pattern that the matcher searches for.
Q_CORE_EXPORT void setCaseSensitivity(Qt::CaseSensitivity cs) noexcept
Sets the case sensitivity to cs.
CaseSensitiveSearcher m_caseSensitiveSearcher
Q_CORE_EXPORT QLatin1StringMatcher() noexcept
Construct an empty Latin-1 string matcher.
constexpr const char * data() const noexcept
constexpr const_iterator end() const noexcept
constexpr QLatin1StringView sliced(qsizetype pos) const
constexpr qsizetype size() const noexcept
\inmodule QtCore
Definition qstringview.h:78
Combined button and popup list for selecting options.
Definition qcompare.h:63
CaseSensitivity
@ CaseInsensitive
@ CaseSensitive
static char32_t foldCase(const char16_t *ch, const char16_t *start)
Definition qchar.cpp:1632
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLuint GLuint end
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLubyte * pattern
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
ptrdiff_t qsizetype
Definition qtypes.h:165