summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2020-05-15 00:03:25 +0200
committerMarc Mutz <marc.mutz@kdab.com>2020-05-17 18:06:17 +0200
commitfae7a47bb3f89ded2d59dc2ad6960e35f252733b (patch)
tree296a9e62052c1ffcf1bcfed65d255047c536d385
parente875f458055d6a7b54d2d853590ccc2495ab145b (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.cpp19
-rw-r--r--src/corelib/text/qstring.cpp18
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());