diff options
Diffstat (limited to 'src/corelib/text/qstring.cpp')
-rw-r--r-- | src/corelib/text/qstring.cpp | 124 |
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) { |