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