Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/QtCore/qstring.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // Copyright (C) 2020 The Qt Company Ltd.
0002 // Copyright (C) 2019 Intel Corporation.
0003 // Copyright (C) 2019 Mail.ru Group.
0004 // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
0005 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0006 // Qt-Security score:critical reason:data-parser
0007 
0008 #ifndef QSTRING_H
0009 #define QSTRING_H
0010 
0011 #if defined(QT_NO_CAST_FROM_ASCII) && defined(QT_RESTRICTED_CAST_FROM_ASCII)
0012 #error QT_NO_CAST_FROM_ASCII and QT_RESTRICTED_CAST_FROM_ASCII must not be defined at the same time
0013 #endif
0014 
0015 #include <QtCore/qchar.h>
0016 #include <QtCore/qcompare.h>
0017 #include <QtCore/qbytearray.h>
0018 #include <QtCore/qbytearrayview.h>
0019 #include <QtCore/qarraydata.h>
0020 #include <QtCore/qlatin1stringview.h>
0021 #include <QtCore/qnamespace.h>
0022 #include <QtCore/qstringliteral.h>
0023 #include <QtCore/qstringalgorithms.h>
0024 #include <QtCore/qanystringview.h>
0025 #include <QtCore/qstringtokenizer.h>
0026 
0027 #include <string>
0028 #include <iterator>
0029 #include <QtCore/q20memory.h>
0030 #include <string_view>
0031 
0032 #include <stdarg.h>
0033 
0034 #ifdef truncate
0035 #error qstring.h must be included before any header file that defines truncate
0036 #endif
0037 
0038 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
0039 Q_FORWARD_DECLARE_CF_TYPE(CFString);
0040 Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
0041 #endif
0042 
0043 class tst_QString;
0044 
0045 QT_BEGIN_NAMESPACE
0046 
0047 class qfloat16;
0048 class QRegularExpression;
0049 class QRegularExpressionMatch;
0050 class QString;
0051 
0052 namespace QtPrivate {
0053 template <bool...B> class BoolList;
0054 
0055 template <typename Char>
0056 using IsCompatibleChar32TypeHelper =
0057     std::is_same<Char, char32_t>;
0058 template <typename Char>
0059 using IsCompatibleChar32Type
0060     = IsCompatibleChar32TypeHelper<q20::remove_cvref_t<Char>>;
0061 
0062 // hack to work around ushort/uchar etc being treated as both characters and
0063 // integers, depending on which Qt API you look at:
0064 template <typename T> struct treat_as_integral_arg : std::false_type {};
0065 template <> struct treat_as_integral_arg<unsigned short> : std::true_type {};
0066 template <> struct treat_as_integral_arg<  signed short> : std::true_type {};
0067 template <> struct treat_as_integral_arg<unsigned  char> : std::true_type {};
0068 template <> struct treat_as_integral_arg<  signed  char> : std::true_type {};
0069 }
0070 
0071 // Qt 4.x compatibility
0072 
0073 //
0074 // QLatin1StringView inline implementations
0075 //
0076 constexpr bool QtPrivate::isLatin1(QLatin1StringView) noexcept
0077 { return true; }
0078 
0079 //
0080 // QStringView members that require QLatin1StringView:
0081 //
0082 int QStringView::compare(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
0083 { return QtPrivate::compareStrings(*this, s, cs); }
0084 bool QStringView::startsWith(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
0085 { return QtPrivate::startsWith(*this, s, cs); }
0086 bool QStringView::endsWith(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
0087 { return QtPrivate::endsWith(*this, s, cs); }
0088 qsizetype QStringView::indexOf(QLatin1StringView s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
0089 { return QtPrivate::findString(*this, from, s, cs); }
0090 bool QStringView::contains(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
0091 { return indexOf(s, 0, cs) != qsizetype(-1); }
0092 qsizetype QStringView::lastIndexOf(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
0093 { return QtPrivate::lastIndexOf(*this, size(), s, cs); }
0094 qsizetype QStringView::lastIndexOf(QLatin1StringView s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
0095 { return QtPrivate::lastIndexOf(*this, from, s, cs); }
0096 qsizetype QStringView::count(QLatin1StringView s, Qt::CaseSensitivity cs) const
0097 { return QtPrivate::count(*this, s, cs); }
0098 
0099 //
0100 // QAnyStringView members that require QLatin1StringView
0101 //
0102 
0103 constexpr QAnyStringView::QAnyStringView(QLatin1StringView str) noexcept
0104     : m_data{str.data()}, m_size{size_t(str.size() << SizeShift) | Tag::Latin1} {}
0105 
0106 constexpr QLatin1StringView QAnyStringView::asLatin1StringView() const
0107 {
0108     Q_ASSERT(isLatin1());
0109     return {m_data_utf8, size()};
0110 }
0111 
0112 
0113 template <typename Visitor>
0114 constexpr decltype(auto) QAnyStringView::visit(Visitor &&v) const
0115 {
0116     if (isUtf16())
0117         return std::forward<Visitor>(v)(asStringView());
0118     else if (isLatin1())
0119         return std::forward<Visitor>(v)(asLatin1StringView());
0120     else
0121         return std::forward<Visitor>(v)(asUtf8StringView());
0122 }
0123 
0124 //
0125 // QAnyStringView members that require QAnyStringView::visit()
0126 //
0127 
0128 constexpr QChar QAnyStringView::front() const
0129 {
0130     return visit([] (auto that) { return QAnyStringView::toQChar(that.front()); });
0131 }
0132 constexpr QChar QAnyStringView::back() const
0133 {
0134     return visit([] (auto that) { return QAnyStringView::toQChar(that.back()); });
0135 }
0136 
0137 
0138 class Q_CORE_EXPORT QString
0139 {
0140     typedef QTypedArrayData<char16_t> Data;
0141 
0142     friend class ::tst_QString;
0143 
0144     template <typename Iterator>
0145     static constexpr bool is_contiguous_iterator_v =
0146         // Can't use contiguous_iterator_tag here, as STL impls can't agree on feature macro.
0147         // To avoid differences in C++20 and C++17 builds, treat only pointers as contiguous
0148         // for now:
0149         // std::contiguous_iterator<Iterator>;
0150         std::is_pointer_v<Iterator>;
0151 
0152     template <typename Char>
0153     using is_compatible_char_helper = std::disjunction<
0154             QtPrivate::IsCompatibleCharType<Char>,
0155             QtPrivate::IsCompatibleChar32Type<Char>,
0156             QtPrivate::IsCompatibleChar8Type<Char>,
0157             std::is_same<Char, QLatin1Char> // special case
0158         >;
0159 
0160     template <typename T>
0161     using is_string_like = std::conjunction<
0162             std::negation<QtPrivate::treat_as_integral_arg<std::remove_cv_t<T>>>, // used to be integral, so keep
0163             std::is_convertible<T, QAnyStringView>
0164         >;
0165 
0166     template <typename T>
0167     using if_string_like = std::enable_if_t<is_string_like<T>::value, bool>;
0168 
0169     template <typename T>
0170     using is_floating_point_like = std::disjunction<
0171         #if QFLOAT16_IS_NATIVE
0172             std::is_same<q20::remove_cvref_t<T>, QtPrivate::NativeFloat16Type>,
0173         #endif
0174             std::is_same<q20::remove_cvref_t<T>, qfloat16>,
0175             std::is_floating_point<T>
0176         >;
0177 
0178     template <typename T>
0179     using if_floating_point = std::enable_if_t<is_floating_point_like<T>::value, bool>;
0180 
0181     template <typename T>
0182     using if_integral_non_char = std::enable_if_t<std::conjunction_v<
0183             std::disjunction< // unlike is_integral, also covers unscoped enums
0184                 std::is_convertible<T, qulonglong>,
0185                 std::is_convertible<T, qlonglong>
0186             >,
0187             std::negation<is_floating_point_like<T>>, // has its own overload
0188             std::negation<is_string_like<T>>          // ditto
0189         >, bool>;
0190 
0191     template <typename Iterator>
0192     static constexpr bool is_compatible_iterator_v = std::conjunction_v<
0193             std::is_convertible<
0194                 typename std::iterator_traits<Iterator>::iterator_category,
0195                 std::input_iterator_tag
0196             >,
0197             is_compatible_char_helper<typename std::iterator_traits<Iterator>::value_type>
0198         >;
0199 
0200     template <typename Iterator>
0201     using if_compatible_iterator = std::enable_if_t<is_compatible_iterator_v<Iterator>, bool>;
0202 
0203 public:
0204     typedef QStringPrivate DataPointer;
0205 
0206     constexpr QString() noexcept;
0207     explicit QString(const QChar *unicode, qsizetype size = -1);
0208     QString(QChar c);
0209     QString(qsizetype size, QChar c);
0210     inline QString(QLatin1StringView latin1);
0211     explicit QString(QStringView sv) : QString(sv.data(), sv.size()) {}
0212 #if defined(__cpp_char8_t) || defined(Q_QDOC)
0213     Q_WEAK_OVERLOAD
0214     inline QString(const char8_t *str)
0215         : QString(fromUtf8(str))
0216     {}
0217 #endif
0218     inline QString(const QString &) noexcept;
0219     inline ~QString();
0220     QString &operator=(QChar c);
0221     QString &operator=(const QString &) noexcept;
0222     QString &operator=(QLatin1StringView latin1);
0223     inline QString(QString &&other) noexcept
0224         = default;
0225     QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QString)
0226     void swap(QString &other) noexcept { d.swap(other.d); }
0227 
0228     static constexpr qsizetype maxSize() noexcept
0229     {
0230         // -1 to deal with the NUL terminator
0231         return Data::maxSize() - 1;
0232     }
0233     constexpr qsizetype size() const noexcept
0234     {
0235 #if __has_cpp_attribute(assume)
0236         constexpr size_t MaxSize = maxSize();
0237         [[assume(size_t(d.size) <= MaxSize)]];
0238 #endif
0239         return d.size;
0240     }
0241 #if QT_DEPRECATED_SINCE(6, 4)
0242     QT_DEPRECATED_VERSION_X_6_4("Use size() or length() instead.")
0243     constexpr qsizetype count() const { return size(); }
0244 #endif
0245     constexpr qsizetype length() const noexcept { return size(); }
0246     constexpr bool isEmpty() const noexcept { return size() == 0; }
0247     void resize(qsizetype size);
0248     void resize(qsizetype size, QChar fillChar);
0249     void resizeForOverwrite(qsizetype size);
0250 
0251     QString &fill(QChar c, qsizetype size = -1);
0252     void truncate(qsizetype pos);
0253     void chop(qsizetype n);
0254 
0255     QString &slice(qsizetype pos)
0256     { verify(pos, 0); return remove(0, pos); }
0257     QString &slice(qsizetype pos, qsizetype n)
0258     {
0259         verify(pos, n);
0260         if (isNull())
0261             return *this;
0262         resize(pos + n);
0263         return remove(0, pos);
0264     }
0265 
0266     inline qsizetype capacity() const;
0267     inline void reserve(qsizetype size);
0268     inline void squeeze();
0269 
0270     inline const QChar *unicode() const;
0271     inline QChar *data();
0272     inline const QChar *data() const;
0273     inline const QChar *constData() const;
0274 
0275     inline void detach();
0276     inline bool isDetached() const;
0277     inline bool isSharedWith(const QString &other) const { return d.isSharedWith(other.d); }
0278     inline void clear();
0279 
0280     inline const QChar at(qsizetype i) const;
0281     inline const QChar operator[](qsizetype i) const;
0282     [[nodiscard]] inline QChar &operator[](qsizetype i);
0283 
0284     [[nodiscard]] inline QChar front() const { return at(0); }
0285     [[nodiscard]] inline QChar &front();
0286     [[nodiscard]] inline QChar back() const { return at(size() - 1); }
0287     [[nodiscard]] inline QChar &back();
0288 
0289 #if QT_CORE_REMOVED_SINCE(6, 9)
0290     [[nodiscard]] QString arg(qlonglong a, int fieldwidth=0, int base=10,
0291                 QChar fillChar = u' ') const;
0292     [[nodiscard]] QString arg(qulonglong a, int fieldwidth=0, int base=10,
0293                 QChar fillChar = u' ') const;
0294     [[nodiscard]] inline QString arg(long a, int fieldwidth=0, int base=10,
0295                 QChar fillChar = u' ') const;
0296     [[nodiscard]] inline QString arg(ulong a, int fieldwidth=0, int base=10,
0297                 QChar fillChar = u' ') const;
0298     [[nodiscard]] inline QString arg(int a, int fieldWidth = 0, int base = 10,
0299                 QChar fillChar = u' ') const;
0300     [[nodiscard]] inline QString arg(uint a, int fieldWidth = 0, int base = 10,
0301                 QChar fillChar = u' ') const;
0302     [[nodiscard]] inline QString arg(short a, int fieldWidth = 0, int base = 10,
0303                 QChar fillChar = u' ') const;
0304     [[nodiscard]] inline QString arg(ushort a, int fieldWidth = 0, int base = 10,
0305                 QChar fillChar = u' ') const;
0306     [[nodiscard]] QString arg(double a, int fieldWidth = 0, char format = 'g', int precision = -1,
0307                 QChar fillChar = u' ') const;
0308     [[nodiscard]] QString arg(char a, int fieldWidth = 0,
0309                 QChar fillChar = u' ') const;
0310     [[nodiscard]] QString arg(QChar a, int fieldWidth = 0,
0311                 QChar fillChar = u' ') const;
0312     [[nodiscard]] QString arg(const QString &a, int fieldWidth = 0,
0313                 QChar fillChar = u' ') const;
0314     [[nodiscard]] QString arg(QStringView a, int fieldWidth = 0,
0315                 QChar fillChar = u' ') const;
0316     [[nodiscard]] QString arg(QLatin1StringView a, int fieldWidth = 0,
0317                 QChar fillChar = u' ') const;
0318 #endif
0319 
0320     template <typename T, if_integral_non_char<T> = true>
0321     [[nodiscard]] QString arg(T a, int fieldWidth = 0, int base = 10,
0322                               QChar fillChar = u' ') const
0323     {
0324         using U = typename std::conditional<
0325                 // underlying_type_t<non-enum> is UB in C++17/SFINAE in C++20, so wrap:
0326                 std::is_enum_v<T>, std::underlying_type<T>,
0327                                    q20::type_identity<T>
0328             >::type::type;
0329         if constexpr (std::is_signed_v<U>)
0330             return arg_impl(qlonglong(a), fieldWidth, base, fillChar);
0331         else
0332             return arg_impl(qulonglong(a), fieldWidth, base, fillChar);
0333     }
0334 
0335     template <typename T, if_floating_point<T> = true>
0336     [[nodiscard]] QString arg(T a, int fieldWidth = 0, char format = 'g', int precision = -1,
0337                               QChar fillChar = u' ') const
0338     { return arg_impl(double(a), fieldWidth, format, precision, fillChar); }
0339 
0340     template <typename T, if_string_like<T> = true>
0341     [[nodiscard]] QString arg(const T &a, int fieldWidth = 0, QChar fillChar = u' ') const
0342     { return arg_impl(QAnyStringView(a), fieldWidth, fillChar); }
0343 
0344 private:
0345     QString arg_impl(qlonglong a, int fieldwidth, int base, QChar fillChar) const;
0346     QString arg_impl(qulonglong a, int fieldwidth, int base, QChar fillChar) const;
0347     QString arg_impl(double a, int fieldWidth, char format, int precision, QChar fillChar) const;
0348     QString arg_impl(QAnyStringView a, int fieldWidth, QChar fillChar) const;
0349 
0350 public:
0351     template <typename...Args>
0352     [[nodiscard]]
0353 #ifdef Q_QDOC
0354     QString
0355 #else
0356     typename std::enable_if<
0357         sizeof...(Args) >= 2 && std::conjunction_v<is_string_like<Args>...>,
0358         QString
0359     >::type
0360 #endif
0361     arg(Args &&...args) const
0362     { return qToStringViewIgnoringNull(*this).arg(std::forward<Args>(args)...); }
0363 
0364     static QString vasprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(1, 0);
0365     static QString asprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
0366 
0367     [[nodiscard]] QT_CORE_INLINE_SINCE(6, 8)
0368     qsizetype indexOf(QChar c, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0369     [[nodiscard]] qsizetype indexOf(QLatin1StringView s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0370     [[nodiscard]] qsizetype indexOf(const QString &s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0371     [[nodiscard]] qsizetype indexOf(QStringView s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
0372     { return QtPrivate::findString(*this, from, s, cs); }
0373     [[nodiscard]] qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
0374     { return lastIndexOf(c, -1, cs); }
0375     [[nodiscard]] QT_CORE_INLINE_SINCE(6, 8)
0376     qsizetype lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0377     [[nodiscard]] qsizetype lastIndexOf(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
0378     { return lastIndexOf(s, size(), cs); }
0379     [[nodiscard]] qsizetype lastIndexOf(QLatin1StringView s, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0380     [[nodiscard]] qsizetype lastIndexOf(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
0381     { return lastIndexOf(s, size(), cs); }
0382     [[nodiscard]] qsizetype lastIndexOf(const QString &s, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0383 
0384     [[nodiscard]] qsizetype lastIndexOf(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
0385     { return lastIndexOf(s, size(), cs); }
0386     [[nodiscard]] qsizetype lastIndexOf(QStringView s, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
0387     { return QtPrivate::lastIndexOf(*this, from, s, cs); }
0388 
0389     [[nodiscard]] inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0390     [[nodiscard]] inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0391     [[nodiscard]] inline bool contains(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0392     [[nodiscard]] inline bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
0393     [[nodiscard]] qsizetype count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0394     [[nodiscard]] qsizetype count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0395     [[nodiscard]] qsizetype count(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0396 
0397 #if QT_CONFIG(regularexpression)
0398     [[nodiscard]] qsizetype indexOf(const QRegularExpression &re, qsizetype from = 0,
0399                                     QRegularExpressionMatch *rmatch = nullptr) const;
0400 #ifdef Q_QDOC
0401     [[nodiscard]] qsizetype lastIndexOf(const QRegularExpression &re, QRegularExpressionMatch *rmatch = nullptr) const;
0402 #else
0403     // prevent an ambiguity when called like this: lastIndexOf(re, 0)
0404     template <typename T = QRegularExpressionMatch, std::enable_if_t<std::is_same_v<T, QRegularExpressionMatch>, bool> = false>
0405     [[nodiscard]] qsizetype lastIndexOf(const QRegularExpression &re, T *rmatch = nullptr) const
0406     { return lastIndexOf(re, size(), rmatch); }
0407 #endif
0408     [[nodiscard]] qsizetype lastIndexOf(const QRegularExpression &re, qsizetype from,
0409                                         QRegularExpressionMatch *rmatch = nullptr) const;
0410     [[nodiscard]] bool contains(const QRegularExpression &re, QRegularExpressionMatch *rmatch = nullptr) const;
0411     [[nodiscard]] qsizetype count(const QRegularExpression &re) const;
0412 #endif
0413 
0414     enum SectionFlag {
0415         SectionDefault             = 0x00,
0416         SectionSkipEmpty           = 0x01,
0417         SectionIncludeLeadingSep   = 0x02,
0418         SectionIncludeTrailingSep  = 0x04,
0419         SectionCaseInsensitiveSeps = 0x08
0420     };
0421     Q_DECLARE_FLAGS(SectionFlags, SectionFlag)
0422 
0423     [[nodiscard]] inline QString section(QChar sep, qsizetype start, qsizetype end = -1, SectionFlags flags = SectionDefault) const;
0424     [[nodiscard]] QString section(const QString &in_sep, qsizetype start, qsizetype end = -1, SectionFlags flags = SectionDefault) const;
0425 #if QT_CONFIG(regularexpression)
0426     [[nodiscard]] QString section(const QRegularExpression &re, qsizetype start, qsizetype end = -1, SectionFlags flags = SectionDefault) const;
0427 #endif
0428 
0429 #if QT_CORE_REMOVED_SINCE(6, 7)
0430     QString left(qsizetype n) const;
0431     QString right(qsizetype n) const;
0432     QString mid(qsizetype position, qsizetype n = -1) const;
0433 
0434     QString first(qsizetype n) const;
0435     QString last(qsizetype n) const;
0436     QString sliced(qsizetype pos) const;
0437     QString sliced(qsizetype pos, qsizetype n) const;
0438     QString chopped(qsizetype n) const;
0439 #else
0440     [[nodiscard]] QString left(qsizetype n) const &
0441     {
0442         if (size_t(n) >= size_t(size()))
0443             return *this;
0444         return first(n);
0445     }
0446     [[nodiscard]] QString left(qsizetype n) &&
0447     {
0448         if (size_t(n) >= size_t(size()))
0449             return std::move(*this);
0450         return std::move(*this).first(n);
0451     }
0452     [[nodiscard]] QString right(qsizetype n) const &
0453     {
0454         if (size_t(n) >= size_t(size()))
0455             return *this;
0456         return last(n);
0457     }
0458     [[nodiscard]] QString right(qsizetype n) &&
0459     {
0460         if (size_t(n) >= size_t(size()))
0461             return std::move(*this);
0462         return std::move(*this).last(n);
0463     }
0464     [[nodiscard]] QString mid(qsizetype position, qsizetype n = -1) const &;
0465     [[nodiscard]] QString mid(qsizetype position, qsizetype n = -1) &&;
0466 
0467     [[nodiscard]] QString first(qsizetype n) const &
0468     { verify(0, n); return sliced(0, n); }
0469     [[nodiscard]] QString last(qsizetype n) const &
0470     { verify(0, n); return sliced(size() - n, n); }
0471     [[nodiscard]] QString sliced(qsizetype pos) const &
0472     { verify(pos, 0); return sliced(pos, size() - pos); }
0473     [[nodiscard]] QString sliced(qsizetype pos, qsizetype n) const &
0474     { verify(pos, n); return QString(begin() + pos, n); }
0475     [[nodiscard]] QString chopped(qsizetype n) const &
0476     { verify(0, n); return sliced(0, size() - n); }
0477 
0478     [[nodiscard]] QString first(qsizetype n) &&
0479     {
0480         verify(0, n);
0481         resize(n);      // may detach and allocate memory
0482         return std::move(*this);
0483     }
0484     [[nodiscard]] QString last(qsizetype n) &&
0485     { verify(0, n); return sliced_helper(*this, size() - n, n); }
0486     [[nodiscard]] QString sliced(qsizetype pos) &&
0487     { verify(pos, 0); return sliced_helper(*this, pos, size() - pos); }
0488     [[nodiscard]] QString sliced(qsizetype pos, qsizetype n) &&
0489     { verify(pos, n); return sliced_helper(*this, pos, n); }
0490     [[nodiscard]] QString chopped(qsizetype n) &&
0491     { verify(0, n); return std::move(*this).first(size() - n); }
0492 #endif
0493     bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0494     [[nodiscard]] bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
0495     { return QtPrivate::startsWith(*this, s, cs); }
0496     bool startsWith(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0497     bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0498 
0499     bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0500     [[nodiscard]] bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
0501     { return QtPrivate::endsWith(*this, s, cs); }
0502     bool endsWith(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0503     bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0504 
0505     bool isUpper() const;
0506     bool isLower() const;
0507 
0508     [[nodiscard]] QString leftJustified(qsizetype width, QChar fill = u' ', bool trunc = false) const;
0509     [[nodiscard]] QString rightJustified(qsizetype width, QChar fill = u' ', bool trunc = false) const;
0510 
0511 #if !defined(Q_QDOC)
0512     [[nodiscard]] QString toLower() const &
0513     { return toLower_helper(*this); }
0514     [[nodiscard]] QString toLower() &&
0515     { return toLower_helper(*this); }
0516     [[nodiscard]] QString toUpper() const &
0517     { return toUpper_helper(*this); }
0518     [[nodiscard]] QString toUpper() &&
0519     { return toUpper_helper(*this); }
0520     [[nodiscard]] QString toCaseFolded() const &
0521     { return toCaseFolded_helper(*this); }
0522     [[nodiscard]] QString toCaseFolded() &&
0523     { return toCaseFolded_helper(*this); }
0524     [[nodiscard]] QString trimmed() const &
0525     { return trimmed_helper(*this); }
0526     [[nodiscard]] QString trimmed() &&
0527     { return trimmed_helper(*this); }
0528     [[nodiscard]] QString simplified() const &
0529     { return simplified_helper(*this); }
0530     [[nodiscard]] QString simplified() &&
0531     { return simplified_helper(*this); }
0532 #else
0533     [[nodiscard]] QString toLower() const;
0534     [[nodiscard]] QString toUpper() const;
0535     [[nodiscard]] QString toCaseFolded() const;
0536     [[nodiscard]] QString trimmed() const;
0537     [[nodiscard]] QString simplified() const;
0538 #endif
0539     [[nodiscard]] QString toHtmlEscaped() const;
0540 
0541     QString &insert(qsizetype i, QChar c);
0542     QString &insert(qsizetype i, const QChar *uc, qsizetype len);
0543     inline QString &insert(qsizetype i, const QString &s) { return insert(i, s.constData(), s.size()); }
0544     inline QString &insert(qsizetype i, QStringView v) { return insert(i, v.data(), v.size()); }
0545     QString &insert(qsizetype i, QLatin1StringView s);
0546     QString &insert(qsizetype i, QUtf8StringView s);
0547 
0548     QString &append(QChar c);
0549     QString &append(const QChar *uc, qsizetype len);
0550     QString &append(const QString &s);
0551     inline QString &append(QStringView v) { return append(v.data(), v.size()); }
0552     QString &append(QLatin1StringView s);
0553     QString &append(QUtf8StringView s);
0554 
0555     inline QString &prepend(QChar c) { return insert(0, c); }
0556     inline QString &prepend(const QChar *uc, qsizetype len) { return insert(0, uc, len); }
0557     inline QString &prepend(const QString &s) { return insert(0, s); }
0558     inline QString &prepend(QStringView v) { return prepend(v.data(), v.size()); }
0559     inline QString &prepend(QLatin1StringView s) { return insert(0, s); }
0560     QString &prepend(QUtf8StringView s) { return insert(0, s); }
0561 
0562     QString &assign(QAnyStringView s);
0563     inline QString &assign(qsizetype n, QChar c)
0564     {
0565         Q_ASSERT(n >= 0);
0566         return fill(c, n);
0567     }
0568     template <typename InputIterator, if_compatible_iterator<InputIterator> = true>
0569     QString &assign(InputIterator first, InputIterator last)
0570     {
0571         using V = typename std::iterator_traits<InputIterator>::value_type;
0572         constexpr bool IsL1C = std::is_same_v<std::remove_cv_t<V>, QLatin1Char>;
0573         constexpr bool IsFwdIt = std::is_convertible_v<
0574                 typename std::iterator_traits<InputIterator>::iterator_category,
0575                 std::forward_iterator_tag
0576             >;
0577 
0578         if constexpr (is_contiguous_iterator_v<InputIterator>) {
0579             const auto p = q20::to_address(first);
0580             const auto len = qsizetype(last - first);
0581             if constexpr (IsL1C)
0582                 return assign(QLatin1StringView(reinterpret_cast<const char*>(p), len));
0583             else if constexpr (sizeof(V) == 4)
0584                 return assign_helper(p, len);
0585             else
0586                 return assign(QAnyStringView(p, len));
0587         } else if constexpr (sizeof(V) == 4) { // non-contiguous iterator, feed data piecemeal
0588             resize(0);
0589             if constexpr (IsFwdIt) {
0590                 const qsizetype requiredCapacity = 2 * std::distance(first, last);
0591                 reserve(requiredCapacity);
0592             }
0593             while (first != last) {
0594                 append(QChar::fromUcs4(*first));
0595                 ++first;
0596             }
0597             return *this;
0598         } else if constexpr (QtPrivate::IsCompatibleChar8Type<V>::value) {
0599             assign_helper_char8(first, last);
0600             if (d.constAllocatedCapacity())
0601                 d.data()[d.size] = u'\0';
0602             return *this;
0603         } else {
0604             d.assign(first, last, [](QChar ch) -> char16_t { return ch.unicode(); });
0605             if (d.constAllocatedCapacity())
0606                 d.data()[d.size] = u'\0';
0607             return *this;
0608         }
0609     }
0610 
0611     inline QString &operator+=(QChar c) { return append(c); }
0612 
0613     inline QString &operator+=(const QString &s) { return append(s); }
0614     inline QString &operator+=(QStringView v) { return append(v); }
0615     inline QString &operator+=(QLatin1StringView s) { return append(s); }
0616     QString &operator+=(QUtf8StringView s) { return append(s); }
0617 
0618 #if defined(QT_RESTRICTED_CAST_FROM_ASCII)
0619     template <qsizetype N>
0620     QString &insert(qsizetype i, const char (&ch)[N]) { return insert(i, QUtf8StringView(ch)); }
0621     template <qsizetype N>
0622     QString &append(const char (&ch)[N]) { return append(QUtf8StringView(ch)); }
0623     template <qsizetype N>
0624     QString &prepend(const char (&ch)[N]) { return prepend(QUtf8StringView(ch)); }
0625     template <qsizetype N>
0626     QString &operator+=(const char (&ch)[N]) { return append(QUtf8StringView(ch)); }
0627 #endif
0628 
0629     QString &remove(qsizetype i, qsizetype len);
0630     QString &remove(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0631     QString &remove(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0632     QString &remove(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0633 
0634     QString &removeAt(qsizetype pos)
0635     { return size_t(pos) < size_t(size()) ? remove(pos, 1) : *this; }
0636     QString &removeFirst() { return !isEmpty() ? remove(0, 1) : *this; }
0637     QString &removeLast() { return !isEmpty() ? remove(size() - 1, 1) : *this; }
0638 
0639     template <typename Predicate>
0640     QString &removeIf(Predicate pred)
0641     {
0642         removeIf_helper(pred);
0643         return *this;
0644     }
0645 
0646     QString &replace(qsizetype i, qsizetype len, QChar after);
0647     QString &replace(qsizetype i, qsizetype len, const QChar *s, qsizetype slen);
0648     QString &replace(qsizetype i, qsizetype len, const QString &after);
0649     QString &replace(QChar before, QChar after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0650     QString &replace(const QChar *before, qsizetype blen, const QChar *after, qsizetype alen, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0651     QString &replace(QLatin1StringView before, QLatin1StringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0652     QString &replace(QLatin1StringView before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0653     QString &replace(const QString &before, QLatin1StringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0654     QString &replace(const QString &before, const QString &after,
0655                      Qt::CaseSensitivity cs = Qt::CaseSensitive);
0656     QString &replace(QChar c, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0657     QString &replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0658 #if QT_CONFIG(regularexpression)
0659     QString &replace(const QRegularExpression &re, const QString  &after);
0660     inline QString &remove(const QRegularExpression &re)
0661     { return replace(re, QString()); }
0662 #endif
0663 
0664 public:
0665     [[nodiscard]]
0666     QStringList split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
0667                       Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0668     [[nodiscard]]
0669     QStringList split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
0670                       Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0671 #ifndef QT_NO_REGULAREXPRESSION
0672     [[nodiscard]]
0673     QStringList split(const QRegularExpression &sep,
0674                       Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
0675 #endif
0676 
0677     template <typename Needle, typename...Flags>
0678     [[nodiscard]] inline auto tokenize(Needle &&needle, Flags...flags) const &
0679         noexcept(noexcept(qTokenize(std::declval<const QString &>(), std::forward<Needle>(needle), flags...)))
0680             -> decltype(qTokenize(*this, std::forward<Needle>(needle), flags...))
0681     { return qTokenize(qToStringViewIgnoringNull(*this), std::forward<Needle>(needle), flags...); }
0682 
0683     template <typename Needle, typename...Flags>
0684     [[nodiscard]] inline auto tokenize(Needle &&needle, Flags...flags) const &&
0685         noexcept(noexcept(qTokenize(std::declval<const QString>(), std::forward<Needle>(needle), flags...)))
0686             -> decltype(qTokenize(std::move(*this), std::forward<Needle>(needle), flags...))
0687     { return qTokenize(std::move(*this), std::forward<Needle>(needle), flags...); }
0688 
0689     template <typename Needle, typename...Flags>
0690     [[nodiscard]] inline auto tokenize(Needle &&needle, Flags...flags) &&
0691         noexcept(noexcept(qTokenize(std::declval<QString>(), std::forward<Needle>(needle), flags...)))
0692             -> decltype(qTokenize(std::move(*this), std::forward<Needle>(needle), flags...))
0693     { return qTokenize(std::move(*this), std::forward<Needle>(needle), flags...); }
0694 
0695 
0696     enum NormalizationForm {
0697         NormalizationForm_D,
0698         NormalizationForm_C,
0699         NormalizationForm_KD,
0700         NormalizationForm_KC
0701     };
0702     [[nodiscard]] QString normalized(NormalizationForm mode, QChar::UnicodeVersion version = QChar::Unicode_Unassigned) const;
0703 
0704     [[nodiscard]] QString repeated(qsizetype times) const;
0705 
0706     const ushort *utf16() const; // ### Qt 7 char16_t
0707     [[nodiscard]] QString nullTerminated() const &;
0708     [[nodiscard]] QString nullTerminated() &&;
0709     QString &nullTerminate();
0710 
0711 #if !defined(Q_QDOC)
0712     [[nodiscard]] QByteArray toLatin1() const &
0713     { return toLatin1_helper(*this); }
0714     [[nodiscard]] QByteArray toLatin1() &&
0715     { return toLatin1_helper_inplace(*this); }
0716     [[nodiscard]] QByteArray toUtf8() const &
0717     { return toUtf8_helper(*this); }
0718     [[nodiscard]] QByteArray toUtf8() &&
0719     { return toUtf8_helper(*this); }
0720     [[nodiscard]] QByteArray toLocal8Bit() const &
0721     { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
0722     [[nodiscard]] QByteArray toLocal8Bit() &&
0723     { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
0724 #else
0725     [[nodiscard]] QByteArray toLatin1() const;
0726     [[nodiscard]] QByteArray toUtf8() const;
0727     [[nodiscard]] QByteArray toLocal8Bit() const;
0728 #endif
0729     [[nodiscard]] QList<uint> toUcs4() const; // ### Qt 7 char32_t
0730 
0731     // note - this are all inline so we can benefit from strlen() compile time optimizations
0732     static QString fromLatin1(QByteArrayView ba);
0733     Q_WEAK_OVERLOAD
0734     static inline QString fromLatin1(const QByteArray &ba) { return fromLatin1(QByteArrayView(ba)); }
0735     static inline QString fromLatin1(const char *str, qsizetype size)
0736     {
0737         return fromLatin1(QByteArrayView(str, !str || size < 0 ? qstrlen(str) : size));
0738     }
0739     static QString fromUtf8(QByteArrayView utf8);
0740     Q_WEAK_OVERLOAD
0741     static inline QString fromUtf8(const QByteArray &ba) { return fromUtf8(QByteArrayView(ba)); }
0742     static inline QString fromUtf8(const char *utf8, qsizetype size)
0743     {
0744         return fromUtf8(QByteArrayView(utf8, !utf8 || size < 0 ? qstrlen(utf8) : size));
0745     }
0746 #if defined(__cpp_char8_t) || defined(Q_QDOC)
0747     Q_WEAK_OVERLOAD
0748     static inline QString fromUtf8(const char8_t *str)
0749     { return fromUtf8(reinterpret_cast<const char *>(str)); }
0750     Q_WEAK_OVERLOAD
0751     static inline QString fromUtf8(const char8_t *str, qsizetype size)
0752     { return fromUtf8(reinterpret_cast<const char *>(str), size); }
0753 #endif
0754     static QString fromLocal8Bit(QByteArrayView ba);
0755     Q_WEAK_OVERLOAD
0756     static inline QString fromLocal8Bit(const QByteArray &ba) { return fromLocal8Bit(QByteArrayView(ba)); }
0757     static inline QString fromLocal8Bit(const char *str, qsizetype size)
0758     {
0759         return fromLocal8Bit(QByteArrayView(str, !str || size < 0 ? qstrlen(str) : size));
0760     }
0761     static QString fromUtf16(const char16_t *, qsizetype size = -1);
0762     static QString fromUcs4(const char32_t *, qsizetype size = -1);
0763     static QString fromRawData(const char16_t *unicode, qsizetype size)
0764     {
0765         return QString(DataPointer::fromRawData(unicode, size));
0766     }
0767     QT_CORE_INLINE_SINCE(6, 10)
0768     static QString fromRawData(const QChar *, qsizetype size);
0769 
0770 #if QT_DEPRECATED_SINCE(6, 0)
0771     QT_DEPRECATED_VERSION_X_6_0("Use char16_t* overload.")
0772     static QString fromUtf16(const ushort *str, qsizetype size = -1)
0773     { return fromUtf16(reinterpret_cast<const char16_t *>(str), size); }
0774     QT_DEPRECATED_VERSION_X_6_0("Use char32_t* overload.")
0775     static QString fromUcs4(const uint *str, qsizetype size = -1)
0776     { return fromUcs4(reinterpret_cast<const char32_t *>(str), size); }
0777 #endif
0778 
0779     inline qsizetype toWCharArray(wchar_t *array) const;
0780     [[nodiscard]] static inline QString fromWCharArray(const wchar_t *string, qsizetype size = -1);
0781 
0782     QString &setRawData(const QChar *unicode, qsizetype size);
0783     QString &setUnicode(const QChar *unicode, qsizetype size);
0784     Q_WEAK_OVERLOAD
0785     QString &setUnicode(const char16_t *utf16, qsizetype size)
0786     { return setUnicode(reinterpret_cast<const QChar *>(utf16), size); }
0787     QString &setUtf16(const char16_t *utf16, qsizetype size)
0788     { return setUnicode(reinterpret_cast<const QChar *>(utf16), size); }
0789 
0790 #if !QT_CORE_REMOVED_SINCE(6, 9)
0791     Q_WEAK_OVERLOAD
0792 #endif
0793     QString &setUtf16(const ushort *autf16, qsizetype asize)
0794     { return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
0795 
0796     int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
0797     int compare(QLatin1StringView other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
0798     inline int compare(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
0799     int compare(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
0800     { return compare(QStringView{&ch, 1}, cs); }
0801 
0802     static inline int compare(const QString &s1, const QString &s2,
0803                               Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
0804     { return s1.compare(s2, cs); }
0805 
0806     static inline int compare(const QString &s1, QLatin1StringView s2,
0807                               Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
0808     { return s1.compare(s2, cs); }
0809     static inline int compare(QLatin1StringView s1, const QString &s2,
0810                               Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
0811     { return -s2.compare(s1, cs); }
0812     static int compare(const QString &s1, QStringView s2, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
0813     { return s1.compare(s2, cs); }
0814     static int compare(QStringView s1, const QString &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
0815     { return -s2.compare(s1, cs); }
0816 
0817     int localeAwareCompare(const QString& s) const;
0818     inline int localeAwareCompare(QStringView s) const;
0819     static int localeAwareCompare(const QString& s1, const QString& s2)
0820     { return s1.localeAwareCompare(s2); }
0821 
0822     static inline int localeAwareCompare(QStringView s1, QStringView s2);
0823 
0824     short toShort(bool *ok=nullptr, int base=10) const
0825     { return toIntegral_helper<short>(*this, ok, base); }
0826     ushort toUShort(bool *ok=nullptr, int base=10) const
0827     { return toIntegral_helper<ushort>(*this, ok, base); }
0828     int toInt(bool *ok=nullptr, int base=10) const
0829     { return toIntegral_helper<int>(*this, ok, base); }
0830     uint toUInt(bool *ok=nullptr, int base=10) const
0831     { return toIntegral_helper<uint>(*this, ok, base); }
0832     long toLong(bool *ok=nullptr, int base=10) const
0833     { return toIntegral_helper<long>(*this, ok, base); }
0834     ulong toULong(bool *ok=nullptr, int base=10) const
0835     { return toIntegral_helper<ulong>(*this, ok, base); }
0836     QT_CORE_INLINE_SINCE(6, 5)
0837     qlonglong toLongLong(bool *ok=nullptr, int base=10) const;
0838     QT_CORE_INLINE_SINCE(6, 5)
0839     qulonglong toULongLong(bool *ok=nullptr, int base=10) const;
0840     float toFloat(bool *ok=nullptr) const;
0841     double toDouble(bool *ok=nullptr) const;
0842 
0843     inline QString &setNum(short, int base=10);
0844     inline QString &setNum(ushort, int base=10);
0845     inline QString &setNum(int, int base=10);
0846     inline QString &setNum(uint, int base=10);
0847     inline QString &setNum(long, int base=10);
0848     inline QString &setNum(ulong, int base=10);
0849     QString &setNum(qlonglong, int base=10);
0850     QString &setNum(qulonglong, int base=10);
0851     inline QString &setNum(float, char format='g', int precision=6);
0852     QString &setNum(double, char format='g', int precision=6);
0853 
0854     static QString number(int, int base=10);
0855     static QString number(uint, int base=10);
0856     static QString number(long, int base=10);
0857     static QString number(ulong, int base=10);
0858     static QString number(qlonglong, int base=10);
0859     static QString number(qulonglong, int base=10);
0860     static QString number(double, char format='g', int precision=6);
0861 
0862     friend bool comparesEqual(const QString &s1, const QString &s2) noexcept
0863     { return comparesEqual(QStringView(s1), QStringView(s2)); }
0864     friend Qt::strong_ordering compareThreeWay(const QString &s1, const QString &s2) noexcept
0865     { return compareThreeWay(QStringView(s1), QStringView(s2)); }
0866     Q_DECLARE_STRONGLY_ORDERED(QString)
0867 
0868     Q_WEAK_OVERLOAD
0869     friend bool comparesEqual(const QString &s1, QUtf8StringView s2) noexcept
0870     { return QtPrivate::equalStrings(s1, s2); }
0871     Q_WEAK_OVERLOAD
0872     friend Qt::strong_ordering compareThreeWay(const QString &s1, QUtf8StringView s2) noexcept
0873     {
0874         const int res = QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive);
0875         return Qt::compareThreeWay(res, 0);
0876     }
0877     Q_DECLARE_STRONGLY_ORDERED(QString, QUtf8StringView, Q_WEAK_OVERLOAD)
0878 
0879 #ifdef __cpp_char8_t
0880     friend bool comparesEqual(const QString &s1, const char8_t *s2) noexcept
0881     { return comparesEqual(s1, QUtf8StringView(s2)); }
0882     friend Qt::strong_ordering compareThreeWay(const QString &s1, const char8_t *s2) noexcept
0883     { return compareThreeWay(s1, QUtf8StringView(s2)); }
0884     Q_DECLARE_STRONGLY_ORDERED(QString, const char8_t *)
0885 #endif // __cpp_char8_t
0886 
0887     friend bool comparesEqual(const QString &s1, QLatin1StringView s2) noexcept
0888     { return (s1.size() == s2.size()) && QtPrivate::equalStrings(s1, s2); }
0889     friend Qt::strong_ordering
0890     compareThreeWay(const QString &s1, QLatin1StringView s2) noexcept
0891     {
0892         const int res = QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive);
0893         return Qt::compareThreeWay(res, 0);
0894     }
0895     Q_DECLARE_STRONGLY_ORDERED(QString, QLatin1StringView)
0896 
0897     // Check isEmpty() instead of isNull() for backwards compatibility.
0898     friend bool comparesEqual(const QString &s1, std::nullptr_t) noexcept
0899     { return s1.isEmpty(); }
0900     friend Qt::strong_ordering compareThreeWay(const QString &s1, std::nullptr_t) noexcept
0901     { return s1.isEmpty() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
0902     Q_DECLARE_STRONGLY_ORDERED(QString, std::nullptr_t)
0903 
0904     friend bool comparesEqual(const QString &s1, const char16_t *s2) noexcept
0905     { return comparesEqual(s1, QStringView(s2)); }
0906     friend Qt::strong_ordering compareThreeWay(const QString &s1, const char16_t *s2) noexcept
0907     { return compareThreeWay(s1, QStringView(s2)); }
0908     Q_DECLARE_STRONGLY_ORDERED(QString, const char16_t *)
0909 
0910     // QChar <> QString
0911     friend bool comparesEqual(const QString &lhs, QChar rhs) noexcept
0912     { return lhs.size() == 1 && rhs == lhs.front(); }
0913     friend Qt::strong_ordering compareThreeWay(const QString &lhs, QChar rhs) noexcept
0914     {
0915         const int res = compare_helper(lhs.data(), lhs.size(), &rhs, 1);
0916         return Qt::compareThreeWay(res, 0);
0917     }
0918     Q_DECLARE_STRONGLY_ORDERED(QString, QChar)
0919 
0920     // ASCII compatibility
0921 #if defined(QT_RESTRICTED_CAST_FROM_ASCII)
0922     template <qsizetype N>
0923     inline QString(const char (&ch)[N])
0924         : QString(fromUtf8(ch))
0925     {}
0926     template <qsizetype N>
0927     QString(char (&)[N]) = delete;
0928     template <qsizetype N>
0929     inline QString &operator=(const char (&ch)[N])
0930     { return (*this = fromUtf8(ch, N - 1)); }
0931     template <qsizetype N>
0932     QString &operator=(char (&)[N]) = delete;
0933 #endif
0934 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
0935     QT_ASCII_CAST_WARN inline QString(const char *ch)
0936         : QString(fromUtf8(ch))
0937     {}
0938     QT_ASCII_CAST_WARN inline QString(const QByteArray &a)
0939         : QString(fromUtf8(a))
0940     {}
0941     QT_ASCII_CAST_WARN inline QString &operator=(const char *ch)
0942     {
0943         if (!ch) {
0944             clear();
0945             return *this;
0946         }
0947         return assign(ch);
0948     }
0949     QT_ASCII_CAST_WARN inline QString &operator=(const QByteArray &a)
0950     {
0951         if (a.isNull()) {
0952             clear();
0953             return *this;
0954         }
0955         return assign(a);
0956     }
0957     // these are needed, so it compiles with STL support enabled
0958     QT_ASCII_CAST_WARN inline QString &prepend(const char *s)
0959     { return prepend(QUtf8StringView(s)); }
0960     QT_ASCII_CAST_WARN inline QString &prepend(const QByteArray &s)
0961     { return prepend(QUtf8StringView(s)); }
0962     QT_ASCII_CAST_WARN inline QString &append(const char *s)
0963     { return append(QUtf8StringView(s)); }
0964     QT_ASCII_CAST_WARN inline QString &append(const QByteArray &s)
0965     { return append(QUtf8StringView(s)); }
0966     QT_ASCII_CAST_WARN inline QString &insert(qsizetype i, const char *s)
0967     { return insert(i, QUtf8StringView(s)); }
0968     QT_ASCII_CAST_WARN inline QString &insert(qsizetype i, const QByteArray &s)
0969     { return insert(i, QUtf8StringView(s)); }
0970     QT_ASCII_CAST_WARN inline QString &operator+=(const char *s)
0971     { return append(QUtf8StringView(s)); }
0972     QT_ASCII_CAST_WARN inline QString &operator+=(const QByteArray &s)
0973     { return append(QUtf8StringView(s)); }
0974 
0975 #if QT_CORE_REMOVED_SINCE(6, 8)
0976     QT_ASCII_CAST_WARN inline bool operator==(const char *s) const;
0977     QT_ASCII_CAST_WARN inline bool operator!=(const char *s) const;
0978     QT_ASCII_CAST_WARN inline bool operator<(const char *s) const;
0979     QT_ASCII_CAST_WARN inline bool operator<=(const char *s) const;
0980     QT_ASCII_CAST_WARN inline bool operator>(const char *s) const;
0981     QT_ASCII_CAST_WARN inline bool operator>=(const char *s) const;
0982 
0983     QT_ASCII_CAST_WARN inline bool operator==(const QByteArray &s) const;
0984     QT_ASCII_CAST_WARN inline bool operator!=(const QByteArray &s) const;
0985     QT_ASCII_CAST_WARN inline bool operator<(const QByteArray &s) const;
0986     QT_ASCII_CAST_WARN inline bool operator>(const QByteArray &s) const;
0987     QT_ASCII_CAST_WARN inline bool operator<=(const QByteArray &s) const;
0988     QT_ASCII_CAST_WARN inline bool operator>=(const QByteArray &s) const;
0989 #else
0990     friend bool comparesEqual(const QString &lhs, QByteArrayView rhs) noexcept
0991     {
0992         return QString::compare_helper(lhs.constData(), lhs.size(),
0993                                        rhs.constData(), rhs.size()) == 0;
0994     }
0995     friend Qt::strong_ordering
0996     compareThreeWay(const QString &lhs, QByteArrayView rhs) noexcept
0997     {
0998         const int res = QString::compare_helper(lhs.constData(), lhs.size(),
0999                                                 rhs.constData(), rhs.size());
1000         return Qt::compareThreeWay(res, 0);
1001     }
1002     Q_DECLARE_STRONGLY_ORDERED(QString, QByteArrayView, QT_ASCII_CAST_WARN)
1003 
1004     friend bool comparesEqual(const QString &lhs, const QByteArray &rhs) noexcept
1005     { return comparesEqual(lhs, QByteArrayView(rhs)); }
1006     friend Qt::strong_ordering
1007     compareThreeWay(const QString &lhs, const QByteArray &rhs) noexcept
1008     {
1009         return compareThreeWay(lhs, QByteArrayView(rhs));
1010     }
1011     Q_DECLARE_STRONGLY_ORDERED(QString, QByteArray, QT_ASCII_CAST_WARN)
1012 
1013     friend bool comparesEqual(const QString &lhs, const char *rhs) noexcept
1014     { return comparesEqual(lhs, QByteArrayView(rhs)); }
1015     friend Qt::strong_ordering
1016     compareThreeWay(const QString &lhs, const char *rhs) noexcept
1017     {
1018         return compareThreeWay(lhs, QByteArrayView(rhs));
1019     }
1020     Q_DECLARE_STRONGLY_ORDERED(QString, const char *, QT_ASCII_CAST_WARN)
1021 #endif // QT_CORE_REMOVED_SINCE(6, 8)
1022 
1023 #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1024 
1025     typedef QChar *iterator;
1026     typedef const QChar *const_iterator;
1027     typedef iterator Iterator;
1028     typedef const_iterator ConstIterator;
1029     typedef std::reverse_iterator<iterator> reverse_iterator;
1030     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1031     inline iterator begin();
1032     inline const_iterator begin() const;
1033     inline const_iterator cbegin() const;
1034     inline const_iterator constBegin() const;
1035     inline iterator end();
1036     inline const_iterator end() const;
1037     inline const_iterator cend() const;
1038     inline const_iterator constEnd() const;
1039     reverse_iterator rbegin() { return reverse_iterator(end()); }
1040     reverse_iterator rend() { return reverse_iterator(begin()); }
1041     const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
1042     const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
1043     const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
1044     const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
1045 
1046     // STL compatibility
1047     typedef qsizetype size_type;
1048     typedef qptrdiff difference_type;
1049     typedef const QChar & const_reference;
1050     typedef QChar & reference;
1051     typedef QChar *pointer;
1052     typedef const QChar *const_pointer;
1053     typedef QChar value_type;
1054     inline void push_back(QChar c) { append(c); }
1055     inline void push_back(const QString &s) { append(s); }
1056     inline void push_front(QChar c) { prepend(c); }
1057     inline void push_front(const QString &s) { prepend(s); }
1058     void shrink_to_fit() { squeeze(); }
1059     iterator erase(const_iterator first, const_iterator last);
1060     inline iterator erase(const_iterator it) { return erase(it, it + 1); }
1061     constexpr qsizetype max_size() const noexcept
1062     {
1063         return maxSize();
1064     }
1065 
1066     static inline QString fromStdString(const std::string &s);
1067     std::string toStdString() const;
1068     static inline QString fromStdWString(const std::wstring &s);
1069     inline std::wstring toStdWString() const;
1070 
1071     static inline QString fromStdU16String(const std::u16string &s);
1072     inline std::u16string toStdU16String() const;
1073     static inline QString fromStdU32String(const std::u32string &s);
1074     inline std::u32string toStdU32String() const;
1075 
1076     Q_IMPLICIT inline operator std::u16string_view() const noexcept;
1077 
1078 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
1079     static QString fromCFString(CFStringRef string);
1080     CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
1081     static QString fromNSString(const NSString *string);
1082     NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
1083 #endif
1084 
1085 #if defined(Q_OS_WASM) || defined(Q_QDOC)
1086     static QString fromEcmaString(emscripten::val jsString);
1087     emscripten::val toEcmaString() const;
1088 #endif
1089 
1090     constexpr bool isNull() const { return d.isNull(); }
1091 
1092     bool isRightToLeft() const;
1093     [[nodiscard]] bool isValidUtf16() const noexcept
1094     { return QStringView(*this).isValidUtf16(); }
1095 
1096     QString(qsizetype size, Qt::Initialization);
1097     explicit QString(DataPointer &&dd) : d(std::move(dd)) {}
1098 
1099 private:
1100 #if defined(QT_NO_CAST_FROM_ASCII)
1101 #define QSTRING_DECL_DELETED_ASCII_OP Q_DECL_EQ_DELETE_X("This function is not available under QT_NO_CAST_FROM_ASCII")
1102     QString &operator+=(const char *s) QSTRING_DECL_DELETED_ASCII_OP;
1103     QString &operator+=(const QByteArray &s) QSTRING_DECL_DELETED_ASCII_OP;
1104     QString(const char *ch) QSTRING_DECL_DELETED_ASCII_OP;
1105     QString(const QByteArray &a) QSTRING_DECL_DELETED_ASCII_OP;
1106     QString &operator=(const char  *ch) QSTRING_DECL_DELETED_ASCII_OP;
1107     QString &operator=(const QByteArray &a) QSTRING_DECL_DELETED_ASCII_OP;
1108 #undef QSTRING_DECL_DELETED_ASCII_OP
1109 #endif
1110 
1111     DataPointer d;
1112     static const char16_t _empty;
1113 
1114     void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
1115     void reallocGrowData(qsizetype n);
1116     // ### remove once QAnyStringView supports UTF-32:
1117     QString &assign_helper(const char32_t *data, qsizetype len);
1118     // Defined in qstringconverter.h
1119     template <typename InputIterator>
1120     void assign_helper_char8(InputIterator first, InputIterator last);
1121     static int compare_helper(const QChar *data1, qsizetype length1,
1122                               const QChar *data2, qsizetype length2,
1123                               Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
1124     static int compare_helper(const QChar *data1, qsizetype length1,
1125                               const char *data2, qsizetype length2,
1126                               Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
1127     static int localeAwareCompare_helper(const QChar *data1, qsizetype length1,
1128                                          const QChar *data2, qsizetype length2);
1129     static QString sliced_helper(QString &str, qsizetype pos, qsizetype n);
1130     static QString toLower_helper(const QString &str);
1131     static QString toLower_helper(QString &str);
1132     static QString toUpper_helper(const QString &str);
1133     static QString toUpper_helper(QString &str);
1134     static QString toCaseFolded_helper(const QString &str);
1135     static QString toCaseFolded_helper(QString &str);
1136     static QString trimmed_helper(const QString &str);
1137     static QString trimmed_helper(QString &str);
1138     static QString simplified_helper(const QString &str);
1139     static QString simplified_helper(QString &str);
1140     static QByteArray toLatin1_helper(const QString &);
1141     static QByteArray toLatin1_helper_inplace(QString &);
1142     static QByteArray toUtf8_helper(const QString &);
1143     static QByteArray toLocal8Bit_helper(const QChar *data, qsizetype size);
1144 #if QT_CORE_REMOVED_SINCE(6, 6)
1145     static qsizetype toUcs4_helper(const ushort *uc, qsizetype length, uint *out);
1146 #endif
1147     static qsizetype toUcs4_helper(const char16_t *uc, qsizetype length, char32_t *out);
1148     static qlonglong toIntegral_helper(QStringView string, bool *ok, int base);
1149     static qulonglong toIntegral_helper(QStringView string, bool *ok, uint base);
1150     template <typename Predicate>
1151     qsizetype removeIf_helper(Predicate pred)
1152     {
1153         const qsizetype result = d->eraseIf(pred);
1154         if (result > 0)
1155             d.data()[d.size] = u'\0';
1156         return result;
1157     }
1158 
1159     friend class QStringView;
1160     friend class QByteArray;
1161     friend struct QAbstractConcatenable;
1162     template <typename T> friend qsizetype erase(QString &s, const T &t);
1163     template <typename Predicate> friend qsizetype erase_if(QString &s, Predicate pred);
1164 
1165     template <typename T> static
1166     T toIntegral_helper(QStringView string, bool *ok, int base)
1167     {
1168         using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
1169         using Int32 = typename std::conditional<std::is_unsigned<T>::value, uint, int>::type;
1170 
1171         // we select the right overload by casting base to int or uint
1172         Int64 val = toIntegral_helper(string, ok, Int32(base));
1173         if (T(val) != val) {
1174             if (ok)
1175                 *ok = false;
1176             val = 0;
1177         }
1178         return T(val);
1179     }
1180 
1181     Q_ALWAYS_INLINE constexpr void verify([[maybe_unused]] qsizetype pos = 0,
1182                                           [[maybe_unused]] qsizetype n = 1) const
1183     {
1184         Q_ASSERT(pos >= 0);
1185         Q_ASSERT(pos <= d.size);
1186         Q_ASSERT(n >= 0);
1187         Q_ASSERT(n <= d.size - pos);
1188     }
1189 
1190 public:
1191     inline DataPointer &data_ptr() { return d; }
1192     inline const DataPointer &data_ptr() const { return d; }
1193 };
1194 
1195 //
1196 // QLatin1StringView inline members that require QUtf8StringView:
1197 //
1198 
1199 int QLatin1StringView::compare(QUtf8StringView other, Qt::CaseSensitivity cs) const noexcept
1200 { return QtPrivate::compareStrings(*this, other, cs); }
1201 
1202 //
1203 // QLatin1StringView inline members that require QString:
1204 //
1205 
1206 QString QLatin1StringView::toString() const { return *this; }
1207 
1208 //
1209 // QStringView inline members that require QUtf8StringView:
1210 //
1211 
1212 int QStringView::compare(QUtf8StringView other, Qt::CaseSensitivity cs) const noexcept
1213 { return QtPrivate::compareStrings(*this, other, cs); }
1214 
1215 //
1216 // QStringView inline members that require QString:
1217 //
1218 
1219 QString QStringView::toString() const
1220 { return QString(*this); }
1221 
1222 qint64 QStringView::toLongLong(bool *ok, int base) const
1223 { return QString::toIntegral_helper<qint64>(*this, ok, base); }
1224 quint64 QStringView::toULongLong(bool *ok, int base) const
1225 { return QString::toIntegral_helper<quint64>(*this, ok, base); }
1226 long QStringView::toLong(bool *ok, int base) const
1227 { return QString::toIntegral_helper<long>(*this, ok, base); }
1228 ulong QStringView::toULong(bool *ok, int base) const
1229 { return QString::toIntegral_helper<ulong>(*this, ok, base); }
1230 int QStringView::toInt(bool *ok, int base) const
1231 { return QString::toIntegral_helper<int>(*this, ok, base); }
1232 uint QStringView::toUInt(bool *ok, int base) const
1233 { return QString::toIntegral_helper<uint>(*this, ok, base); }
1234 short QStringView::toShort(bool *ok, int base) const
1235 { return QString::toIntegral_helper<short>(*this, ok, base); }
1236 ushort QStringView::toUShort(bool *ok, int base) const
1237 { return QString::toIntegral_helper<ushort>(*this, ok, base); }
1238 
1239 //
1240 // QUtf8StringView inline members that require QStringView:
1241 //
1242 
1243 template <bool UseChar8T>
1244 int QBasicUtf8StringView<UseChar8T>::compare(QChar other, Qt::CaseSensitivity cs) const noexcept
1245 {
1246     return QtPrivate::compareStrings(*this, QStringView(&other, 1), cs);
1247 }
1248 
1249 template <bool UseChar8T>
1250 int QBasicUtf8StringView<UseChar8T>::compare(QStringView other, Qt::CaseSensitivity cs) const noexcept
1251 {
1252     return QtPrivate::compareStrings(*this, other, cs);
1253 }
1254 
1255 template <bool UseChar8T>
1256 [[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(QChar other) const noexcept
1257 {
1258     return QtPrivate::equalStrings(*this, QStringView(&other, 1));
1259 }
1260 
1261 template <bool UseChar8T>
1262 [[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(QStringView other) const noexcept
1263 {
1264     return QtPrivate::equalStrings(*this, other);
1265 }
1266 
1267 //
1268 // QUtf8StringView inline members that require QString, QL1SV or QBA:
1269 //
1270 
1271 template <bool UseChar8T>
1272 QString QBasicUtf8StringView<UseChar8T>::toString() const
1273 {
1274     return QString::fromUtf8(data(), size());
1275 }
1276 
1277 template<bool UseChar8T>
1278 [[nodiscard]] int QBasicUtf8StringView<UseChar8T>::compare(QLatin1StringView other,
1279                                                            Qt::CaseSensitivity cs) const noexcept
1280 {
1281     return QtPrivate::compareStrings(*this, other, cs);
1282 }
1283 
1284 template<bool UseChar8T>
1285 [[nodiscard]] int QBasicUtf8StringView<UseChar8T>::compare(const QByteArray &other,
1286                                                            Qt::CaseSensitivity cs) const noexcept
1287 {
1288     return QtPrivate::compareStrings(*this,
1289                                      QBasicUtf8StringView<UseChar8T>(other.data(), other.size()),
1290                                      cs);
1291 }
1292 
1293 template <bool UseChar8T>
1294 [[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(QLatin1StringView other) const noexcept
1295 {
1296     return QtPrivate::equalStrings(*this, other);
1297 }
1298 
1299 template <bool UseChar8T>
1300 [[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(const QByteArray &other) const noexcept
1301 {
1302     return size() == other.size()
1303             && QtPrivate::equalStrings(*this, QBasicUtf8StringView<UseChar8T>(other.data(),
1304                                                                               other.size()));
1305 }
1306 
1307 //
1308 // QAnyStringView inline members that require QString:
1309 //
1310 
1311 QAnyStringView::QAnyStringView(const QByteArray &str) noexcept
1312     : QAnyStringView{str.begin(), str.size()} {}
1313 QAnyStringView::QAnyStringView(const QString &str) noexcept
1314     : QAnyStringView{str.begin(), str.size()} {}
1315 
1316 QString QAnyStringView::toString() const
1317 { return QtPrivate::convertToQString(*this); }
1318 
1319 //
1320 // QString inline members
1321 //
1322 QString::QString(QLatin1StringView latin1)
1323     : QString{QString::fromLatin1(latin1.data(), latin1.size())} {}
1324 const QChar QString::at(qsizetype i) const
1325 { verify(i, 1); return QChar(d.data()[i]); }
1326 const QChar QString::operator[](qsizetype i) const
1327 { verify(i, 1); return QChar(d.data()[i]); }
1328 const QChar *QString::unicode() const
1329 { return data(); }
1330 const QChar *QString::data() const
1331 {
1332 #if QT5_NULL_STRINGS == 1
1333     return reinterpret_cast<const QChar *>(d.data() ? d.data() : &_empty);
1334 #else
1335     return reinterpret_cast<const QChar *>(d.data());
1336 #endif
1337 }
1338 QChar *QString::data()
1339 {
1340     detach();
1341     Q_ASSERT(d.data());
1342     return reinterpret_cast<QChar *>(d.data());
1343 }
1344 const QChar *QString::constData() const
1345 { return data(); }
1346 void QString::detach()
1347 { if (d.needsDetach()) reallocData(d.size, QArrayData::KeepSize); }
1348 bool QString::isDetached() const
1349 { return !d.isShared(); }
1350 void QString::clear()
1351 { if (!isNull()) *this = QString(); }
1352 QString::QString(const QString &other) noexcept : d(other.d)
1353 { }
1354 qsizetype QString::capacity() const { return qsizetype(d.constAllocatedCapacity()); }
1355 QString &QString::setNum(short n, int base)
1356 { return setNum(qlonglong(n), base); }
1357 QString &QString::setNum(ushort n, int base)
1358 { return setNum(qulonglong(n), base); }
1359 QString &QString::setNum(int n, int base)
1360 { return setNum(qlonglong(n), base); }
1361 QString &QString::setNum(uint n, int base)
1362 { return setNum(qulonglong(n), base); }
1363 QString &QString::setNum(long n, int base)
1364 { return setNum(qlonglong(n), base); }
1365 QString &QString::setNum(ulong n, int base)
1366 { return setNum(qulonglong(n), base); }
1367 QString &QString::setNum(float n, char f, int prec)
1368 { return setNum(double(n),f,prec); }
1369 #if QT_CORE_REMOVED_SINCE(6, 9)
1370 QString QString::arg(int a, int fieldWidth, int base, QChar fillChar) const
1371 { return arg(qlonglong(a), fieldWidth, base, fillChar); }
1372 QString QString::arg(uint a, int fieldWidth, int base, QChar fillChar) const
1373 { return arg(qulonglong(a), fieldWidth, base, fillChar); }
1374 QString QString::arg(long a, int fieldWidth, int base, QChar fillChar) const
1375 { return arg(qlonglong(a), fieldWidth, base, fillChar); }
1376 QString QString::arg(ulong a, int fieldWidth, int base, QChar fillChar) const
1377 { return arg(qulonglong(a), fieldWidth, base, fillChar); }
1378 QString QString::arg(short a, int fieldWidth, int base, QChar fillChar) const
1379 { return arg(qlonglong(a), fieldWidth, base, fillChar); }
1380 QString QString::arg(ushort a, int fieldWidth, int base, QChar fillChar) const
1381 { return arg(qulonglong(a), fieldWidth, base, fillChar); }
1382 #endif // QT_CORE_REMOVED_SINCE
1383 
1384 QString QString::section(QChar asep, qsizetype astart, qsizetype aend, SectionFlags aflags) const
1385 { return section(QString(asep), astart, aend, aflags); }
1386 
1387 QT_WARNING_PUSH
1388 QT_WARNING_DISABLE_MSVC(4127)   // "conditional expression is constant"
1389 QT_WARNING_DISABLE_INTEL(111)   // "statement is unreachable"
1390 
1391 qsizetype QString::toWCharArray(wchar_t *array) const
1392 {
1393     return qToStringViewIgnoringNull(*this).toWCharArray(array);
1394 }
1395 
1396 qsizetype QStringView::toWCharArray(wchar_t *array) const
1397 {
1398     if (sizeof(wchar_t) == sizeof(QChar)) {
1399         if (auto src = data())
1400             memcpy(array, src, sizeof(QChar) * size());
1401         return size();
1402     } else {
1403         return QString::toUcs4_helper(utf16(), size(), reinterpret_cast<char32_t *>(array));
1404     }
1405 }
1406 
1407 QT_WARNING_POP
1408 
1409 QString QString::fromWCharArray(const wchar_t *string, qsizetype size)
1410 {
1411     if constexpr (sizeof(wchar_t) == sizeof(QChar)) {
1412         return QString(reinterpret_cast<const QChar *>(string), size);
1413     } else {
1414 #ifdef QT_BOOTSTRAPPED
1415         Q_UNREACHABLE_RETURN(QString());
1416 #else
1417         return fromUcs4(reinterpret_cast<const char32_t *>(string), size);
1418 #endif
1419     }
1420 }
1421 
1422 constexpr QString::QString() noexcept {}
1423 QString::~QString() {}
1424 
1425 void QString::reserve(qsizetype asize)
1426 {
1427     if (d.needsDetach() || asize >= capacity() - d.freeSpaceAtBegin())
1428         reallocData(qMax(asize, size()), QArrayData::KeepSize);
1429     if (d.constAllocatedCapacity())
1430         d.setFlag(Data::CapacityReserved);
1431 }
1432 
1433 void QString::squeeze()
1434 {
1435     if (!d.isMutable())
1436         return;
1437     if (d.needsDetach() || size() < capacity())
1438         reallocData(d.size, QArrayData::KeepSize);
1439     if (d.constAllocatedCapacity())
1440         d.clearFlag(Data::CapacityReserved);
1441 }
1442 
1443 QChar &QString::operator[](qsizetype i)
1444 { verify(i, 1); return data()[i]; }
1445 QChar &QString::front() { return operator[](0); }
1446 QChar &QString::back() { return operator[](size() - 1); }
1447 QString::iterator QString::begin()
1448 { detach(); return reinterpret_cast<QChar*>(d.data()); }
1449 QString::const_iterator QString::begin() const
1450 { return reinterpret_cast<const QChar*>(d.data()); }
1451 QString::const_iterator QString::cbegin() const
1452 { return reinterpret_cast<const QChar*>(d.data()); }
1453 QString::const_iterator QString::constBegin() const
1454 { return reinterpret_cast<const QChar*>(d.data()); }
1455 QString::iterator QString::end()
1456 { detach(); return reinterpret_cast<QChar*>(d.data() + d.size); }
1457 QString::const_iterator QString::end() const
1458 { return reinterpret_cast<const QChar*>(d.data() + d.size); }
1459 QString::const_iterator QString::cend() const
1460 { return reinterpret_cast<const QChar*>(d.data() + d.size); }
1461 QString::const_iterator QString::constEnd() const
1462 { return reinterpret_cast<const QChar*>(d.data() + d.size); }
1463 bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
1464 { return indexOf(s, 0, cs) != -1; }
1465 bool QString::contains(QLatin1StringView s, Qt::CaseSensitivity cs) const
1466 { return indexOf(s, 0, cs) != -1; }
1467 bool QString::contains(QChar c, Qt::CaseSensitivity cs) const
1468 { return indexOf(c, 0, cs) != -1; }
1469 bool QString::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
1470 { return indexOf(s, 0, cs) != -1; }
1471 
1472 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1473 #if QT_CORE_REMOVED_SINCE(6, 8)
1474 bool QString::operator==(const char *s) const
1475 { return QString::compare_helper(constData(), size(), s, -1) == 0; }
1476 bool QString::operator!=(const char *s) const
1477 { return QString::compare_helper(constData(), size(), s, -1) != 0; }
1478 bool QString::operator<(const char *s) const
1479 { return QString::compare_helper(constData(), size(), s, -1) < 0; }
1480 bool QString::operator>(const char *s) const
1481 { return QString::compare_helper(constData(), size(), s, -1) > 0; }
1482 bool QString::operator<=(const char *s) const
1483 { return QString::compare_helper(constData(), size(), s, -1) <= 0; }
1484 bool QString::operator>=(const char *s) const
1485 { return QString::compare_helper(constData(), size(), s, -1) >= 0; }
1486 
1487 QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const
1488 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) == 0; }
1489 QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const
1490 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) != 0; }
1491 QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const
1492 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; }
1493 QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const
1494 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) > 0; }
1495 QT_ASCII_CAST_WARN bool QString::operator<=(const QByteArray &s) const
1496 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) <= 0; }
1497 QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const
1498 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; }
1499 
1500 bool QByteArray::operator==(const QString &s) const
1501 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) == 0; }
1502 bool QByteArray::operator!=(const QString &s) const
1503 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) != 0; }
1504 bool QByteArray::operator<(const QString &s) const
1505 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; }
1506 bool QByteArray::operator>(const QString &s) const
1507 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) < 0; }
1508 bool QByteArray::operator<=(const QString &s) const
1509 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) >= 0; }
1510 bool QByteArray::operator>=(const QString &s) const
1511 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) <= 0; }
1512 #endif // QT_CORE_REMOVED_SINCE(6, 8)
1513 #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1514 
1515 #if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
1516 // QString + QString
1517 inline QString operator+(const QString &s1, const QString &s2)
1518 { QString t(s1); t += s2; return t; }
1519 inline QString operator+(QString &&lhs, const QString &rhs)
1520 { return std::move(lhs += rhs); }
1521 inline QString operator+(const QString &s1, QChar s2)
1522 { QString t(s1); t += s2; return t; }
1523 inline QString operator+(QString &&lhs, QChar rhs)
1524 { return std::move(lhs += rhs); }
1525 inline QString operator+(QChar s1, const QString &s2)
1526 { QString t(s1); t += s2; return t; }
1527 inline QString operator+(const QString &lhs, QStringView rhs)
1528 {
1529     QString ret{lhs.size() + rhs.size(), Qt::Uninitialized};
1530     return ret.assign(lhs).append(rhs);
1531 }
1532 inline QString operator+(QStringView lhs, const QString &rhs)
1533 {
1534     QString ret{lhs.size() + rhs.size(), Qt::Uninitialized};
1535     return ret.assign(lhs).append(rhs);
1536 }
1537 
1538 #  if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1539 QT_ASCII_CAST_WARN inline QString operator+(const QString &s1, const char *s2)
1540 { QString t(s1); t += QUtf8StringView(s2); return t; }
1541 QT_ASCII_CAST_WARN inline QString operator+(QString &&lhs, const char *rhs)
1542 { QT_IGNORE_DEPRECATIONS(return std::move(lhs += rhs);) }
1543 QT_ASCII_CAST_WARN inline QString operator+(const char *s1, const QString &s2)
1544 { QString t = QString::fromUtf8(s1); t += s2; return t; }
1545 QT_ASCII_CAST_WARN inline QString operator+(const QByteArray &ba, const QString &s)
1546 { QString t = QString::fromUtf8(ba); t += s; return t; }
1547 QT_ASCII_CAST_WARN inline QString operator+(const QString &s, const QByteArray &ba)
1548 { QString t(s); t += QUtf8StringView(ba); return t; }
1549 QT_ASCII_CAST_WARN inline QString operator+(QString &&lhs, const QByteArray &rhs)
1550 { QT_IGNORE_DEPRECATIONS(return std::move(lhs += rhs);) }
1551 #  endif // QT_NO_CAST_FROM_ASCII
1552 #endif // QT_USE_QSTRINGBUILDER
1553 
1554 QString QString::fromStdString(const std::string &s)
1555 { return fromUtf8(s.data(), qsizetype(s.size())); }
1556 
1557 std::wstring QString::toStdWString() const
1558 {
1559     std::wstring str;
1560     str.resize(size());
1561     str.resize(toWCharArray(str.data()));
1562     return str;
1563 }
1564 
1565 QString QString::fromStdWString(const std::wstring &s)
1566 { return fromWCharArray(s.data(), qsizetype(s.size())); }
1567 
1568 QString QString::fromStdU16String(const std::u16string &s)
1569 { return fromUtf16(s.data(), qsizetype(s.size())); }
1570 
1571 std::u16string QString::toStdU16String() const
1572 { return std::u16string(reinterpret_cast<const char16_t*>(data()), size()); }
1573 
1574 QString QString::fromStdU32String(const std::u32string &s)
1575 { return fromUcs4(s.data(), qsizetype(s.size())); }
1576 
1577 std::u32string QString::toStdU32String() const
1578 {
1579     std::u32string u32str(size(), char32_t(0));
1580     const qsizetype len = toUcs4_helper(reinterpret_cast<const char16_t *>(data()),
1581                                         size(), u32str.data());
1582     u32str.resize(len);
1583     return u32str;
1584 }
1585 
1586 QString::operator std::u16string_view() const noexcept
1587 {
1588     return std::u16string_view(d.data(), size_t(d.size));
1589 }
1590 
1591 #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
1592 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QString &);
1593 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QString &);
1594 #endif
1595 
1596 Q_DECLARE_SHARED(QString)
1597 Q_DECLARE_OPERATORS_FOR_FLAGS(QString::SectionFlags)
1598 
1599 int QString::compare(QStringView s, Qt::CaseSensitivity cs) const noexcept
1600 { return -s.compare(*this, cs); }
1601 
1602 int QString::localeAwareCompare(QStringView s) const
1603 { return localeAwareCompare_helper(constData(), size(), s.constData(), s.size()); }
1604 int QString::localeAwareCompare(QStringView s1, QStringView s2)
1605 { return localeAwareCompare_helper(s1.constData(), s1.size(), s2.constData(), s2.size()); }
1606 int QStringView::localeAwareCompare(QStringView other) const
1607 { return QString::localeAwareCompare(*this, other); }
1608 
1609 #if QT_CORE_INLINE_IMPL_SINCE(6, 5)
1610 qint64 QString::toLongLong(bool *ok, int base) const
1611 {
1612     return toIntegral_helper<qlonglong>(*this, ok, base);
1613 }
1614 
1615 quint64 QString::toULongLong(bool *ok, int base) const
1616 {
1617     return toIntegral_helper<qulonglong>(*this, ok, base);
1618 }
1619 #endif
1620 #if QT_CORE_INLINE_IMPL_SINCE(6, 8)
1621 qsizetype QString::indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const
1622 {
1623     return qToStringViewIgnoringNull(*this).indexOf(ch, from, cs);
1624 }
1625 qsizetype QString::lastIndexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const
1626 {
1627     return qToStringViewIgnoringNull(*this).lastIndexOf(ch, from, cs);
1628 }
1629 #endif
1630 #if QT_CORE_INLINE_IMPL_SINCE(6, 10)
1631 QString QString::fromRawData(const QChar *unicode, qsizetype size)
1632 {
1633     return fromRawData(reinterpret_cast<const char16_t *>(unicode), size);
1634 }
1635 #endif
1636 
1637 namespace QtPrivate {
1638 // used by qPrintable() and qUtf8Printable() macros
1639 inline const QString &asString(const QString &s)    { return s; }
1640 inline QString &&asString(QString &&s)              { return std::move(s); }
1641 }
1642 
1643 #ifndef qPrintable
1644 #  define qPrintable(string) QtPrivate::asString(string).toLocal8Bit().constData()
1645 #endif
1646 
1647 #ifndef qUtf8Printable
1648 #  define qUtf8Printable(string) QtPrivate::asString(string).toUtf8().constData()
1649 #endif
1650 
1651 /*
1652     Wrap QString::utf16() with enough casts to allow passing it
1653     to QString::asprintf("%ls") without warnings.
1654 */
1655 #ifndef qUtf16Printable
1656 #  define qUtf16Printable(string) \
1657     static_cast<const wchar_t*>(static_cast<const void*>(QtPrivate::asString(string).utf16()))
1658 #endif
1659 
1660 //
1661 // QStringView::arg() implementation
1662 //
1663 
1664 namespace QtPrivate {
1665 
1666 struct ArgBase {
1667     enum Tag : uchar { L1, Any, U16 } tag;
1668 };
1669 
1670 struct QStringViewArg : ArgBase {
1671     QStringView string;
1672     QStringViewArg() = default;
1673     constexpr explicit QStringViewArg(QStringView v) noexcept : ArgBase{U16}, string{v} {}
1674 };
1675 
1676 struct QLatin1StringArg : ArgBase {
1677     QLatin1StringView string;
1678     QLatin1StringArg() = default;
1679     constexpr explicit QLatin1StringArg(QLatin1StringView v) noexcept : ArgBase{L1}, string{v} {}
1680 };
1681 
1682 struct QAnyStringArg : ArgBase {
1683     QAnyStringView string;
1684     QAnyStringArg() = default;
1685     constexpr explicit QAnyStringArg(QAnyStringView v) noexcept : ArgBase{Any}, string{v} {}
1686 };
1687 
1688 #if QT_CORE_REMOVED_SINCE(6, 9)
1689 [[nodiscard]] Q_CORE_EXPORT QString argToQString(QStringView pattern, size_t n, const ArgBase **args);
1690 [[nodiscard]] Q_CORE_EXPORT QString argToQString(QLatin1StringView pattern, size_t n, const ArgBase **args);
1691 #endif
1692 [[nodiscard]] Q_CORE_EXPORT QString argToQString(QAnyStringView pattern, size_t n, const ArgBase **args);
1693 
1694 template <typename...Args>
1695 [[nodiscard]] Q_ALWAYS_INLINE QString argToQStringDispatch(QAnyStringView pattern, const Args &...args)
1696 {
1697     const ArgBase *argBases[] = {&args..., /* avoid zero-sized array */ nullptr};
1698     return QtPrivate::argToQString(pattern, sizeof...(Args), argBases);
1699 }
1700 
1701 constexpr inline QAnyStringArg qStringLikeToArg(QAnyStringView s) noexcept { return QAnyStringArg{s}; }
1702 
1703 } // namespace QtPrivate
1704 
1705 template <typename...Args>
1706 Q_ALWAYS_INLINE
1707 QString QStringView::arg(Args &&...args) const
1708 {
1709     return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1710 }
1711 
1712 template <typename...Args>
1713 Q_ALWAYS_INLINE
1714 QString QLatin1StringView::arg(Args &&...args) const
1715 {
1716     return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1717 }
1718 
1719 template <bool HasChar8T>
1720 template <typename...Args>
1721 QString QBasicUtf8StringView<HasChar8T>::arg(Args &&...args) const
1722 {
1723     return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1724 }
1725 
1726 template <typename...Args>
1727 QString QAnyStringView::arg(Args &&...args) const
1728 {
1729     return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1730 }
1731 
1732 template <typename T>
1733 qsizetype erase(QString &s, const T &t)
1734 {
1735     return s.removeIf_helper([&t](const auto &e) { return t == e; });
1736 }
1737 
1738 template <typename Predicate>
1739 qsizetype erase_if(QString &s, Predicate pred)
1740 {
1741     return s.removeIf_helper(pred);
1742 }
1743 
1744 namespace Qt {
1745 inline namespace Literals {
1746 inline namespace StringLiterals {
1747 inline QString operator""_s(const char16_t *str, size_t size) noexcept
1748 {
1749     return QString(QStringPrivate(nullptr, const_cast<char16_t *>(str), qsizetype(size)));
1750 }
1751 
1752 } // StringLiterals
1753 } // Literals
1754 } // Qt
1755 
1756 inline namespace QtLiterals {
1757 #if QT_DEPRECATED_SINCE(6, 8)
1758 
1759 QT_DEPRECATED_VERSION_X_6_8("Use _s from Qt::StringLiterals namespace instead.")
1760 inline QString operator""_qs(const char16_t *str, size_t size) noexcept
1761 {
1762     return Qt::StringLiterals::operator""_s(str, size);
1763 }
1764 
1765 #endif // QT_DEPRECATED_SINCE(6, 8)
1766 } // QtLiterals
1767 
1768 QT_END_NAMESPACE
1769 
1770 #include <QtCore/qstringbuilder.h>
1771 #include <QtCore/qstringconverter.h>
1772 
1773 #ifdef Q_L1S_VIEW_IS_PRIMARY
1774 #    undef Q_L1S_VIEW_IS_PRIMARY
1775 #endif
1776 
1777 #endif // QSTRING_H