diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2020-05-15 00:03:25 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2020-05-17 18:06:17 +0200 |
commit | fae7a47bb3f89ded2d59dc2ad6960e35f252733b (patch) | |
tree | 296a9e62052c1ffcf1bcfed65d255047c536d385 | |
parent | e875f458055d6a7b54d2d853590ccc2495ab145b (diff) |
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>
-rw-r--r-- | src/corelib/text/qchar.cpp | 19 | ||||
-rw-r--r-- | src/corelib/text/qstring.cpp | 18 |
2 files changed, 22 insertions, 15 deletions
diff --git a/src/corelib/text/qchar.cpp b/src/corelib/text/qchar.cpp index 49622bf196..358cc82f22 100644 --- a/src/corelib/text/qchar.cpp +++ b/src/corelib/text/qchar.cpp @@ -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; } diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index c22dd0bd91..1765ca0aa1 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -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()); |