Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:38

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