QChar: make fullConvertCase()'s result type more usable
Move it into the function, give it an explicit size and make it iterable and indicate to QStringView that it's a compatible container. Change-Id: I483d9225ac73ad93f2037489f2d32473c377e8b7 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
e875f45805
commit
fae7a47bb3
@ -1590,11 +1590,21 @@ QChar::UnicodeVersion QChar::currentUnicodeVersion() noexcept
|
||||
return UNICODE_DATA_VERSION;
|
||||
}
|
||||
|
||||
using FullConvertCaseResult = std::array<char16_t, MaxSpecialCaseLength + 1>;
|
||||
static FullConvertCaseResult fullConvertCase(char32_t uc, QUnicodeTables::Case which) noexcept
|
||||
static auto fullConvertCase(char32_t uc, QUnicodeTables::Case which) noexcept
|
||||
{
|
||||
FullConvertCaseResult result = {};
|
||||
auto pp = result.begin();
|
||||
struct R {
|
||||
char16_t chars[MaxSpecialCaseLength + 1];
|
||||
qint8 sz;
|
||||
|
||||
// iterable
|
||||
auto begin() const { return chars; }
|
||||
auto end() const { return chars + sz; }
|
||||
// QStringView-compatible
|
||||
auto data() const { return chars; }
|
||||
auto size() const { return sz; }
|
||||
} result;
|
||||
|
||||
auto pp = result.chars;
|
||||
|
||||
const auto fold = qGetProp(uc)->cases[which];
|
||||
const auto caseDiff = fold.diff;
|
||||
@ -1609,6 +1619,7 @@ static FullConvertCaseResult fullConvertCase(char32_t uc, QUnicodeTables::Case w
|
||||
for (char16_t c : QChar::fromUcs4(uc + caseDiff))
|
||||
*pp++ = c;
|
||||
}
|
||||
result.sz = pp - result.chars;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -6148,31 +6148,27 @@ static QString detachAndConvertCase(T &str, QStringIterator it, QUnicodeTables::
|
||||
|
||||
do {
|
||||
const auto folded = fullConvertCase(it.nextUnchecked(), which);
|
||||
if (Q_UNLIKELY(folded[1])) {
|
||||
if (folded[0] == *pp && !folded[2]) {
|
||||
if (Q_UNLIKELY(folded.size() > 1)) {
|
||||
if (folded.chars[0] == *pp && folded.size() == 2) {
|
||||
// special case: only second actually changed (e.g. surrogate pairs),
|
||||
// avoid slow case
|
||||
++pp;
|
||||
*pp++ = folded[1];
|
||||
*pp++ = folded.chars[1];
|
||||
} else {
|
||||
// slow path: the string is growing
|
||||
int inpos = it.index() - 1;
|
||||
int outpos = pp - s.constBegin();
|
||||
|
||||
int foldedSize = 2; // must be at least 2, b/c folded[1] != NUL
|
||||
while (folded[foldedSize])
|
||||
++foldedSize;
|
||||
|
||||
s.replace(outpos, 1, reinterpret_cast<const QChar *>(folded.data()), foldedSize);
|
||||
pp = const_cast<QChar *>(s.constBegin()) + outpos + foldedSize;
|
||||
s.replace(outpos, 1, reinterpret_cast<const QChar *>(folded.data()), folded.size());
|
||||
pp = const_cast<QChar *>(s.constBegin()) + outpos + folded.size();
|
||||
|
||||
// do we need to adjust the input iterator too?
|
||||
// if it is pointing to s's data, str is empty
|
||||
if (str.isEmpty())
|
||||
it = QStringIterator(s.constBegin(), inpos + foldedSize, s.constEnd());
|
||||
it = QStringIterator(s.constBegin(), inpos + folded.size(), s.constEnd());
|
||||
}
|
||||
} else {
|
||||
*pp++ = folded[0];
|
||||
*pp++ = folded.chars[0];
|
||||
}
|
||||
} while (it.hasNext());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user