summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qstring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qstring.cpp')
-rw-r--r--src/corelib/text/qstring.cpp124
1 files changed, 66 insertions, 58 deletions
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index fe9790403f..2d0e4531d1 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -63,8 +63,8 @@
#endif
#define REHASH(a) \
- if (sl_minus_1 < sizeof(std::size_t) * CHAR_BIT) \
- hashHaystack -= std::size_t(a) << sl_minus_1; \
+ if (sl_minus_1 < sizeof(sl_minus_1) * CHAR_BIT) \
+ hashHaystack -= decltype(hashHaystack)(a) << sl_minus_1; \
hashHaystack <<= 1
QT_BEGIN_NAMESPACE
@@ -183,10 +183,10 @@ static qsizetype qLastIndexOf(Haystack haystack0, qsizetype from,
const auto needle = needle0.data();
const auto *end = haystack;
haystack += from;
- const std::size_t sl_minus_1 = sl ? sl - 1 : 0;
+ const qregisteruint sl_minus_1 = sl ? sl - 1 : 0;
const auto *n = needle + sl_minus_1;
const auto *h = haystack + sl_minus_1;
- std::size_t hashNeedle = 0, hashHaystack = 0;
+ qregisteruint hashNeedle = 0, hashHaystack = 0;
if (cs == Qt::CaseSensitive) {
for (qsizetype idx = 0; idx < sl; ++idx) {
@@ -361,7 +361,7 @@ extern "C" void qt_toLatin1_mips_dsp_asm(uchar *dst, const char16_t *src, int le
#if defined(__SSE2__) && defined(Q_CC_GNU)
// We may overrun the buffer, but that's a false positive:
// this won't crash nor produce incorrect results
-# define ATTRIBUTE_NO_SANITIZE __attribute__((__no_sanitize_address__))
+# define ATTRIBUTE_NO_SANITIZE __attribute__((__no_sanitize_address__, __no_sanitize_thread__))
#else
# define ATTRIBUTE_NO_SANITIZE
#endif
@@ -657,7 +657,7 @@ static int ucstrncmp_sse2(const char16_t *a, const Char *b, size_t l)
Q_NEVER_INLINE
qsizetype QtPrivate::qustrlen(const char16_t *str) noexcept
{
-#if defined(__SSE2__) && !(defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer))
+#if defined(__SSE2__) && !(defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)) && !(defined(__SANITIZE_THREAD__) || __has_feature(thread_sanitizer))
return qustrlen_sse2(str);
#endif
@@ -1543,6 +1543,8 @@ int QtPrivate::compareStrings(QLatin1StringView lhs, QLatin1StringView rhs, Qt::
{
if (lhs.isEmpty())
return qt_lencmp(qsizetype(0), rhs.size());
+ if (rhs.isEmpty())
+ return qt_lencmp(lhs.size(), qsizetype(0));
if (cs == Qt::CaseInsensitive)
return latin1nicmp(lhs.data(), lhs.size(), rhs.data(), rhs.size());
const auto l = std::min(lhs.size(), rhs.size());
@@ -5251,8 +5253,9 @@ QString QString::section(const QRegularExpression &re, qsizetype start, qsizetyp
\fn QString QString::left(qsizetype n) const &
\fn QString QString::left(qsizetype n) &&
- Returns a substring that contains the \a n leftmost characters
- of the string.
+ Returns a substring that contains the \a n leftmost characters of
+ this string (that is, from the beginning of this string up to, but not
+ including, the element at index position \a n).
If you know that \a n cannot be out of bounds, use first() instead in new
code, because it is faster.
@@ -5283,8 +5286,9 @@ QString QString::section(const QRegularExpression &re, qsizetype start, qsizetyp
\fn QString QString::mid(qsizetype position, qsizetype n) const &
\fn QString QString::mid(qsizetype position, qsizetype n) &&
- Returns a string that contains \a n characters of this string,
- starting at the specified \a position index.
+ Returns a string that contains \a n characters of this string, starting
+ at the specified \a position index up to, but not including, the element
+ at index position \c {\a position + n}.
If you know that \a position and \a n cannot be out of bounds, use sliced()
instead in new code, because it is faster.
@@ -5339,8 +5343,9 @@ QString QString::mid(qsizetype position, qsizetype n) &&
\fn QString QString::first(qsizetype n) &&
\since 6.0
- Returns a string that contains the first \a n characters
- of this string.
+ Returns a string that contains the first \a n characters of this string,
+ (that is, from the beginning of this string up to, but not including,
+ the element at index position \a n).
\note The behavior is undefined when \a n < 0 or \a n > size().
@@ -5368,8 +5373,9 @@ QString QString::mid(qsizetype position, qsizetype n) &&
\fn QString QString::sliced(qsizetype pos, qsizetype n) &&
\since 6.0
- Returns a string that contains \a n characters of this string,
- starting at position \a pos.
+ Returns a string that contains \a n characters of this string, starting
+ at position \a pos up to, but not including, the element at index position
+ \c {\a pos + n}.
\note The behavior is undefined when \a pos < 0, \a n < 0,
or \a pos + \a n > size().
@@ -5405,8 +5411,9 @@ QString QString::sliced_helper(QString &str, qsizetype pos, qsizetype n)
\fn QString &QString::slice(qsizetype pos, qsizetype n)
\since 6.8
- Modifies this string to start at position \a pos, extending for \a n
- characters (code points), and returns a reference to this string.
+ Modifies this string to start at position \a pos, up to, but not including,
+ the character (code point) at index position \c {\a pos + n}; and returns
+ a reference to this string.
\note The behavior is undefined if \a pos < 0, \a n < 0,
or \a pos + \a n > size().
@@ -6302,7 +6309,8 @@ QString QString::trimmed_helper(QString &str)
/*!
\fn void QString::truncate(qsizetype position)
- Truncates the string at the given \a position index.
+ Truncates the string starting from, and including, the element at index
+ \a position.
If the specified \a position index is beyond the end of the
string, nothing happens.
@@ -9077,7 +9085,7 @@ static inline char16_t to_unicode(const QChar c) { return c.unicode(); }
static inline char16_t to_unicode(const char c) { return QLatin1Char{c}.unicode(); }
template <typename Char>
-static int getEscape(const Char *uc, qsizetype *pos, qsizetype len, int maxNumber = 999)
+static int getEscape(const Char *uc, qsizetype *pos, qsizetype len)
{
qsizetype i = *pos;
++i;
@@ -9088,17 +9096,16 @@ static int getEscape(const Char *uc, qsizetype *pos, qsizetype len, int maxNumbe
if (uint(escape) >= 10U)
return -1;
++i;
- while (i < len) {
+ if (i < len) {
+ // there's a second digit
int digit = to_unicode(uc[i]) - '0';
- if (uint(digit) >= 10U)
- break;
- escape = (escape * 10) + digit;
- ++i;
- }
- if (escape <= maxNumber) {
- *pos = i;
- return escape;
+ if (uint(digit) < 10U) {
+ escape = (escape * 10) + digit;
+ ++i;
+ }
}
+ *pos = i;
+ return escape;
}
return -1;
}
@@ -9141,18 +9148,13 @@ namespace {
struct Part
{
Part() = default; // for QVarLengthArray; do not use
- constexpr Part(QStringView s, int num = -1)
- : tag{QtPrivate::ArgBase::U16}, number{num}, data{s.utf16()}, size{s.size()} {}
- constexpr Part(QLatin1StringView s, int num = -1)
- : tag{QtPrivate::ArgBase::L1}, number{num}, data{s.data()}, size{s.size()} {}
+ constexpr Part(QAnyStringView s, int num = -1)
+ : string{s}, number{num} {}
- void reset(QStringView s) noexcept { *this = {s, number}; }
- void reset(QLatin1StringView s) noexcept { *this = {s, number}; }
+ void reset(QAnyStringView s) noexcept { *this = {s, number}; }
- QtPrivate::ArgBase::Tag tag;
+ QAnyStringView string;
int number;
- const void *data;
- qsizetype size;
};
} // unnamed namespace
@@ -9235,16 +9237,13 @@ static qsizetype resolveStringRefsAndReturnTotalSize(ParseResult &parts, const A
}
}
}
- totalSize += part.size;
+ totalSize += part.string.size();
}
return totalSize;
}
} // unnamed namespace
-Q_ALWAYS_INLINE QString to_string(QLatin1StringView s) noexcept { return s; }
-Q_ALWAYS_INLINE QString to_string(QStringView s) noexcept { return s.toString(); }
-
template <typename StringView>
static QString argToQStringImpl(StringView pattern, size_t numArgs, const QtPrivate::ArgBase **args)
{
@@ -9258,7 +9257,7 @@ static QString argToQStringImpl(StringView pattern, size_t numArgs, const QtPriv
argIndexToPlaceholderMap.resize(qsizetype(numArgs));
else if (Q_UNLIKELY(static_cast<size_t>(argIndexToPlaceholderMap.size()) < numArgs)) // 3b
qWarning("QString::arg: %d argument(s) missing in %ls",
- int(numArgs - argIndexToPlaceholderMap.size()), qUtf16Printable(to_string(pattern)));
+ int(numArgs - argIndexToPlaceholderMap.size()), qUtf16Printable(pattern.toString()));
// 5
const qsizetype totalSize = resolveStringRefsAndReturnTotalSize(parts, argIndexToPlaceholderMap, args);
@@ -9267,24 +9266,33 @@ static QString argToQStringImpl(StringView pattern, size_t numArgs, const QtPriv
QString result(totalSize, Qt::Uninitialized);
auto out = const_cast<QChar*>(result.constData());
- for (const Part &part : parts) {
- switch (part.tag) {
- case QtPrivate::ArgBase::L1:
- if (part.size) {
+ struct Concatenate {
+ QChar *out;
+ QChar *operator()(QLatin1String part) noexcept
+ {
+ if (part.size()) {
qt_from_latin1(reinterpret_cast<char16_t*>(out),
- reinterpret_cast<const char*>(part.data), part.size);
+ part.data(), part.size());
}
- break;
- case QtPrivate::ArgBase::U8:
- Q_UNREACHABLE(); // waiting for QUtf8String
- break;
- case QtPrivate::ArgBase::U16:
- if (part.size)
- memcpy(out, part.data, part.size * sizeof(QChar));
- break;
+ return out + part.size();
}
- out += part.size;
- }
+ QChar *operator()(QUtf8StringView part) noexcept
+ {
+ return QUtf8::convertToUnicode(out, part);
+ }
+ QChar *operator()(QStringView part) noexcept
+ {
+ if (part.size())
+ memcpy(out, part.data(), part.size() * sizeof(QChar));
+ return out + part.size();
+ }
+ };
+
+ for (const Part &part : parts)
+ out = part.string.visit(Concatenate{out});
+
+ // UTF-8 decoding may have caused an overestimate of totalSize - correct it:
+ result.truncate(out - result.cbegin());
return result;
}
@@ -9906,8 +9914,8 @@ qsizetype QtPrivate::findString(QStringView haystack0, qsizetype from, QStringVi
const char16_t *needle = needle0.utf16();
const char16_t *haystack = haystack0.utf16() + from;
const char16_t *end = haystack0.utf16() + (l - sl);
- const std::size_t sl_minus_1 = sl - 1;
- std::size_t hashNeedle = 0, hashHaystack = 0;
+ const qregisteruint sl_minus_1 = sl - 1;
+ qregisteruint hashNeedle = 0, hashHaystack = 0;
qsizetype idx;
if (cs == Qt::CaseSensitive) {