Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qstring.h
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2019 Intel Corporation.
3// Copyright (C) 2019 Mail.ru Group.
4// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
5// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
6
7#ifndef QSTRING_H
8#define QSTRING_H
9
10#if defined(QT_NO_CAST_FROM_ASCII) && defined(QT_RESTRICTED_CAST_FROM_ASCII)
11#error QT_NO_CAST_FROM_ASCII and QT_RESTRICTED_CAST_FROM_ASCII must not be defined at the same time
12#endif
13
14#include <QtCore/qchar.h>
15#include <QtCore/qcompare.h>
16#include <QtCore/qbytearray.h>
17#include <QtCore/qbytearrayview.h>
18#include <QtCore/qarraydata.h>
19#include <QtCore/qlatin1stringview.h>
20#include <QtCore/qnamespace.h>
21#include <QtCore/qstringliteral.h>
22#include <QtCore/qstringalgorithms.h>
23#include <QtCore/qanystringview.h>
24#include <QtCore/qstringtokenizer.h>
25
26#include <string>
27#include <iterator>
28#include <QtCore/q20memory.h>
29#include <string_view>
30
31#include <stdarg.h>
32
33#ifdef truncate
34#error qstring.h must be included before any header file that defines truncate
35#endif
36
37#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
38Q_FORWARD_DECLARE_CF_TYPE(CFString);
39Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
40#endif
41
42class tst_QString;
43
44QT_BEGIN_NAMESPACE
45
46class qfloat16;
47class QRegularExpression;
48class QRegularExpressionMatch;
49class QString;
50
51namespace QtPrivate {
52template <bool...B> class BoolList;
53
54template <typename Char>
55using IsCompatibleChar32TypeHelper =
56 std::is_same<Char, char32_t>;
57template <typename Char>
60
61// hack to work around ushort/uchar etc being treated as both characters and
62// integers, depending on which Qt API you look at:
63template <typename T> struct treat_as_integral_arg : std::false_type {};
64template <> struct treat_as_integral_arg<unsigned short> : std::true_type {};
65template <> struct treat_as_integral_arg< signed short> : std::true_type {};
66template <> struct treat_as_integral_arg<unsigned char> : std::true_type {};
67template <> struct treat_as_integral_arg< signed char> : std::true_type {};
68// QTBUG-126054, keep until we can fix it for all platforms, not just Windows
69// (where wchar_t does convert to QAnyStringView):
70template <> struct treat_as_integral_arg<wchar_t> : std::true_type {};
71}
72
73// Qt 4.x compatibility
74
75//
76// QLatin1StringView inline implementations
77//
78constexpr bool QtPrivate::isLatin1(QLatin1StringView) noexcept
79{ return true; }
80
81//
82// QStringView members that require QLatin1StringView:
83//
84int QStringView::compare(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
85{ return QtPrivate::compareStrings(*this, s, cs); }
86bool QStringView::startsWith(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
87{ return QtPrivate::startsWith(*this, s, cs); }
88bool QStringView::endsWith(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
89{ return QtPrivate::endsWith(*this, s, cs); }
90qsizetype QStringView::indexOf(QLatin1StringView s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
91{ return QtPrivate::findString(*this, from, s, cs); }
92bool QStringView::contains(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
93{ return indexOf(s, 0, cs) != qsizetype(-1); }
94qsizetype QStringView::lastIndexOf(QLatin1StringView s, Qt::CaseSensitivity cs) const noexcept
95{ return QtPrivate::lastIndexOf(*this, size(), s, cs); }
96qsizetype QStringView::lastIndexOf(QLatin1StringView s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
97{ return QtPrivate::lastIndexOf(*this, from, s, cs); }
98qsizetype QStringView::count(QLatin1StringView s, Qt::CaseSensitivity cs) const
99{ return QtPrivate::count(*this, s, cs); }
100
101//
102// QAnyStringView members that require QLatin1StringView
103//
104
105constexpr QAnyStringView::QAnyStringView(QLatin1StringView str) noexcept
106 : m_data{str.data()}, m_size{size_t(str.size() << SizeShift) | Tag::Latin1} {}
107
108constexpr QLatin1StringView QAnyStringView::asLatin1StringView() const
109{
110 Q_ASSERT(isLatin1());
111 return {m_data_utf8, size()};
112}
113
114
115template <typename Visitor>
116constexpr decltype(auto) QAnyStringView::visit(Visitor &&v) const
117{
118 if (isUtf16())
119 return std::forward<Visitor>(v)(asStringView());
120 else if (isLatin1())
121 return std::forward<Visitor>(v)(asLatin1StringView());
122 else
123 return std::forward<Visitor>(v)(asUtf8StringView());
124}
125
126//
127// QAnyStringView members that require QAnyStringView::visit()
128//
129
130constexpr QChar QAnyStringView::front() const
131{
132 return visit([] (auto that) { return QAnyStringView::toQChar(that.front()); });
133}
134constexpr QChar QAnyStringView::back() const
135{
136 return visit([] (auto that) { return QAnyStringView::toQChar(that.back()); });
137}
138
139
140class Q_CORE_EXPORT QString
141{
142 typedef QTypedArrayData<char16_t> Data;
143
144 friend class ::tst_QString;
145
146 template <typename Iterator>
147 static constexpr bool is_contiguous_iterator_v =
148 // Can't use contiguous_iterator_tag here, as STL impls can't agree on feature macro.
149 // To avoid differences in C++20 and C++17 builds, treat only pointers as contiguous
150 // for now:
151 // std::contiguous_iterator<Iterator>;
152 std::is_pointer_v<Iterator>;
153
154 template <typename Char>
155 using is_compatible_char_helper = std::disjunction<
156 QtPrivate::IsCompatibleCharType<Char>,
157 QtPrivate::IsCompatibleChar32Type<Char>,
158 QtPrivate::IsCompatibleChar8Type<Char>,
159 std::is_same<Char, QLatin1Char> // special case
160 >;
161
162 template <typename T>
163 using is_string_like = std::conjunction<
164 std::negation<QtPrivate::treat_as_integral_arg<std::remove_cv_t<T>>>, // used to be integral, so keep
165 std::is_convertible<T, QAnyStringView>
166 >;
167
168 template <typename T>
169 using if_string_like = std::enable_if_t<is_string_like<T>::value, bool>;
170
171 template <typename T>
172 using is_floating_point_like = std::disjunction<
173 #if QFLOAT16_IS_NATIVE
174 std::is_same<q20::remove_cvref_t<T>, QtPrivate::NativeFloat16Type>,
175 #endif
176 std::is_same<q20::remove_cvref_t<T>, qfloat16>,
177 std::is_floating_point<T>
178 >;
179
180 template <typename T>
181 using if_floating_point = std::enable_if_t<is_floating_point_like<T>::value, bool>;
182
183 template <typename T>
184 using if_integral_non_char = std::enable_if_t<std::conjunction_v<
185 std::disjunction< // unlike is_integral, also covers unscoped enums
186 std::is_convertible<T, qulonglong>,
187 std::is_convertible<T, qlonglong>
188 >,
189 std::negation<is_floating_point_like<T>>, // has its own overload
190 std::negation<is_string_like<T>> // ditto
191 >, bool>;
192
193 template <typename Iterator>
194 static constexpr bool is_compatible_iterator_v = std::conjunction_v<
195 std::is_convertible<
196 typename std::iterator_traits<Iterator>::iterator_category,
197 std::input_iterator_tag
198 >,
199 is_compatible_char_helper<typename std::iterator_traits<Iterator>::value_type>
200 >;
201
202 template <typename Iterator>
203 using if_compatible_iterator = std::enable_if_t<is_compatible_iterator_v<Iterator>, bool>;
204
205public:
206 typedef QStringPrivate DataPointer;
207
208 constexpr QString() noexcept;
209 explicit QString(const QChar *unicode, qsizetype size = -1);
210 QString(QChar c);
211 QString(qsizetype size, QChar c);
212 inline QString(QLatin1StringView latin1);
213 explicit QString(QStringView sv) : QString(sv.data(), sv.size()) {}
214#if defined(__cpp_char8_t) || defined(Q_QDOC)
215 Q_WEAK_OVERLOAD
216 inline QString(const char8_t *str)
217 : QString(fromUtf8(str))
218 {}
219#endif
220 inline QString(const QString &) noexcept;
221 inline ~QString();
222 QString &operator=(QChar c);
223 QString &operator=(const QString &) noexcept;
224 QString &operator=(QLatin1StringView latin1);
225 inline QString(QString &&other) noexcept
226 = default;
227 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QString)
228 void swap(QString &other) noexcept { d.swap(other.d); }
229
230 static constexpr qsizetype maxSize() noexcept
231 {
232 // -1 to deal with the NUL terminator
233 return Data::maxSize() - 1;
234 }
235 constexpr qsizetype size() const noexcept
236 {
237#if __has_cpp_attribute(assume)
238 constexpr size_t MaxSize = maxSize();
239 [[assume(size_t(d.size) <= MaxSize)]];
240#endif
241 return d.size;
242 }
243#if QT_DEPRECATED_SINCE(6, 4)
244 QT_DEPRECATED_VERSION_X_6_4("Use size() or length() instead.")
245 constexpr qsizetype count() const { return size(); }
246#endif
247 constexpr qsizetype length() const noexcept { return size(); }
248 constexpr bool isEmpty() const noexcept { return size() == 0; }
249 void resize(qsizetype size);
250 void resize(qsizetype size, QChar fillChar);
251 void resizeForOverwrite(qsizetype size);
252
253 QString &fill(QChar c, qsizetype size = -1);
254 void truncate(qsizetype pos);
255 void chop(qsizetype n);
256
257 QString &slice(qsizetype pos)
258 { verify(pos, 0); return remove(0, pos); }
259 QString &slice(qsizetype pos, qsizetype n)
260 {
261 verify(pos, n);
262 if (isNull())
263 return *this;
264 resize(pos + n);
265 return remove(0, pos);
266 }
267
268 inline qsizetype capacity() const;
269 inline void reserve(qsizetype size);
270 inline void squeeze();
271
272 inline const QChar *unicode() const;
273 inline QChar *data();
274 inline const QChar *data() const;
275 inline const QChar *constData() const;
276
277 inline void detach();
278 inline bool isDetached() const;
279 inline bool isSharedWith(const QString &other) const { return d.isSharedWith(other.d); }
280 inline void clear();
281
282 inline const QChar at(qsizetype i) const;
283 inline const QChar operator[](qsizetype i) const;
284 [[nodiscard]] inline QChar &operator[](qsizetype i);
285
286 [[nodiscard]] inline QChar front() const { return at(0); }
287 [[nodiscard]] inline QChar &front();
288 [[nodiscard]] inline QChar back() const { return at(size() - 1); }
289 [[nodiscard]] inline QChar &back();
290
291#if QT_CORE_REMOVED_SINCE(6, 9)
292 [[nodiscard]] QString arg(qlonglong a, int fieldwidth=0, int base=10,
293 QChar fillChar = u' ') const;
294 [[nodiscard]] QString arg(qulonglong a, int fieldwidth=0, int base=10,
295 QChar fillChar = u' ') const;
296 [[nodiscard]] inline QString arg(long a, int fieldwidth=0, int base=10,
297 QChar fillChar = u' ') const;
298 [[nodiscard]] inline QString arg(ulong a, int fieldwidth=0, int base=10,
299 QChar fillChar = u' ') const;
300 [[nodiscard]] inline QString arg(int a, int fieldWidth = 0, int base = 10,
301 QChar fillChar = u' ') const;
302 [[nodiscard]] inline QString arg(uint a, int fieldWidth = 0, int base = 10,
303 QChar fillChar = u' ') const;
304 [[nodiscard]] inline QString arg(short a, int fieldWidth = 0, int base = 10,
305 QChar fillChar = u' ') const;
306 [[nodiscard]] inline QString arg(ushort a, int fieldWidth = 0, int base = 10,
307 QChar fillChar = u' ') const;
308 [[nodiscard]] QString arg(double a, int fieldWidth = 0, char format = 'g', int precision = -1,
309 QChar fillChar = u' ') const;
310 [[nodiscard]] QString arg(char a, int fieldWidth = 0,
311 QChar fillChar = u' ') const;
312 [[nodiscard]] QString arg(QChar a, int fieldWidth = 0,
313 QChar fillChar = u' ') const;
314 [[nodiscard]] QString arg(const QString &a, int fieldWidth = 0,
315 QChar fillChar = u' ') const;
316 [[nodiscard]] QString arg(QStringView a, int fieldWidth = 0,
317 QChar fillChar = u' ') const;
318 [[nodiscard]] QString arg(QLatin1StringView a, int fieldWidth = 0,
319 QChar fillChar = u' ') const;
320#endif
322 template <typename T, if_integral_non_char<T> = true>
323 [[nodiscard]] QString arg(T a, int fieldWidth = 0, int base = 10,
324 QChar fillChar = u' ') const
325 {
326 using U = typename std::conditional<
327 // underlying_type_t<non-enum> is UB in C++17/SFINAE in C++20, so wrap:
328 std::is_enum_v<T>, std::underlying_type<T>,
329 q20::type_identity<T>
330 >::type::type;
331 if constexpr (std::is_signed_v<U>)
332 return arg_impl(qlonglong(a), fieldWidth, base, fillChar);
333 else
334 return arg_impl(qulonglong(a), fieldWidth, base, fillChar);
335 }
336
337 template <typename T, if_floating_point<T> = true>
338 [[nodiscard]] QString arg(T a, int fieldWidth = 0, char format = 'g', int precision = -1,
339 QChar fillChar = u' ') const
340 { return arg_impl(double(a), fieldWidth, format, precision, fillChar); }
341
342 template <typename T, if_string_like<T> = true>
343 [[nodiscard]] QString arg(const T &a, int fieldWidth = 0, QChar fillChar = u' ') const
344 { return arg_impl(QAnyStringView(a), fieldWidth, fillChar); }
345
346private:
347 QString arg_impl(qlonglong a, int fieldwidth, int base, QChar fillChar) const;
348 QString arg_impl(qulonglong a, int fieldwidth, int base, QChar fillChar) const;
349 QString arg_impl(double a, int fieldWidth, char format, int precision, QChar fillChar) const;
350 QString arg_impl(QAnyStringView a, int fieldWidth, QChar fillChar) const;
351
352public:
353 template <typename...Args>
354 [[nodiscard]]
355#ifdef Q_QDOC
356 QString
357#else
358 typename std::enable_if<
359 sizeof...(Args) >= 2 && std::conjunction_v<is_string_like<Args>...>,
360 QString
361 >::type
362#endif
363 arg(Args &&...args) const
364 { return qToStringViewIgnoringNull(*this).arg(std::forward<Args>(args)...); }
365
366 static QString vasprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(1, 0);
367 static QString asprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
368
369 [[nodiscard]] QT_CORE_INLINE_SINCE(6, 8)
370 qsizetype indexOf(QChar c, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
371 [[nodiscard]] qsizetype indexOf(QLatin1StringView s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
372 [[nodiscard]] qsizetype indexOf(const QString &s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
373 [[nodiscard]] qsizetype indexOf(QStringView s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
374 { return QtPrivate::findString(*this, from, s, cs); }
375 [[nodiscard]] qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
376 { return lastIndexOf(c, -1, cs); }
377 [[nodiscard]] QT_CORE_INLINE_SINCE(6, 8)
378 qsizetype lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
379 [[nodiscard]] qsizetype lastIndexOf(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
380 { return lastIndexOf(s, size(), cs); }
381 [[nodiscard]] qsizetype lastIndexOf(QLatin1StringView s, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
382 [[nodiscard]] qsizetype lastIndexOf(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
383 { return lastIndexOf(s, size(), cs); }
384 [[nodiscard]] qsizetype lastIndexOf(const QString &s, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
385
386 [[nodiscard]] qsizetype lastIndexOf(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
387 { return lastIndexOf(s, size(), cs); }
388 [[nodiscard]] qsizetype lastIndexOf(QStringView s, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
389 { return QtPrivate::lastIndexOf(*this, from, s, cs); }
390
391 [[nodiscard]] inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
392 [[nodiscard]] inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
393 [[nodiscard]] inline bool contains(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
394 [[nodiscard]] inline bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
395 [[nodiscard]] qsizetype count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
396 [[nodiscard]] qsizetype count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
397 [[nodiscard]] qsizetype count(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
398
399#if QT_CONFIG(regularexpression)
400 [[nodiscard]] qsizetype indexOf(const QRegularExpression &re, qsizetype from = 0,
401 QRegularExpressionMatch *rmatch = nullptr) const;
402#ifdef Q_QDOC
403 [[nodiscard]] qsizetype lastIndexOf(const QRegularExpression &re, QRegularExpressionMatch *rmatch = nullptr) const;
404#else
405 // prevent an ambiguity when called like this: lastIndexOf(re, 0)
406 template <typename T = QRegularExpressionMatch, std::enable_if_t<std::is_same_v<T, QRegularExpressionMatch>, bool> = false>
407 [[nodiscard]] qsizetype lastIndexOf(const QRegularExpression &re, T *rmatch = nullptr) const
408 { return lastIndexOf(re, size(), rmatch); }
409#endif
410 [[nodiscard]] qsizetype lastIndexOf(const QRegularExpression &re, qsizetype from,
411 QRegularExpressionMatch *rmatch = nullptr) const;
412 [[nodiscard]] bool contains(const QRegularExpression &re, QRegularExpressionMatch *rmatch = nullptr) const;
413 [[nodiscard]] qsizetype count(const QRegularExpression &re) const;
414#endif
415
416 enum SectionFlag {
417 SectionDefault = 0x00,
418 SectionSkipEmpty = 0x01,
419 SectionIncludeLeadingSep = 0x02,
420 SectionIncludeTrailingSep = 0x04,
421 SectionCaseInsensitiveSeps = 0x08
422 };
423 Q_DECLARE_FLAGS(SectionFlags, SectionFlag)
424
425 [[nodiscard]] inline QString section(QChar sep, qsizetype start, qsizetype end = -1, SectionFlags flags = SectionDefault) const;
426 [[nodiscard]] QString section(const QString &in_sep, qsizetype start, qsizetype end = -1, SectionFlags flags = SectionDefault) const;
427#if QT_CONFIG(regularexpression)
428 [[nodiscard]] QString section(const QRegularExpression &re, qsizetype start, qsizetype end = -1, SectionFlags flags = SectionDefault) const;
429#endif
430
431#if QT_CORE_REMOVED_SINCE(6, 7)
432 QString left(qsizetype n) const;
433 QString right(qsizetype n) const;
434 QString mid(qsizetype position, qsizetype n = -1) const;
435
436 QString first(qsizetype n) const;
437 QString last(qsizetype n) const;
438 QString sliced(qsizetype pos) const;
439 QString sliced(qsizetype pos, qsizetype n) const;
440 QString chopped(qsizetype n) const;
441#else
442 [[nodiscard]] QString left(qsizetype n) const &
443 {
444 if (size_t(n) >= size_t(size()))
445 return *this;
446 return first(n);
447 }
448 [[nodiscard]] QString left(qsizetype n) &&
449 {
450 if (size_t(n) >= size_t(size()))
451 return std::move(*this);
452 return std::move(*this).first(n);
453 }
454 [[nodiscard]] QString right(qsizetype n) const &
455 {
456 if (size_t(n) >= size_t(size()))
457 return *this;
458 return last(n);
459 }
460 [[nodiscard]] QString right(qsizetype n) &&
461 {
462 if (size_t(n) >= size_t(size()))
463 return std::move(*this);
464 return std::move(*this).last(n);
465 }
466 [[nodiscard]] QString mid(qsizetype position, qsizetype n = -1) const &;
467 [[nodiscard]] QString mid(qsizetype position, qsizetype n = -1) &&;
468
469 [[nodiscard]] QString first(qsizetype n) const &
470 { verify(0, n); return sliced(0, n); }
471 [[nodiscard]] QString last(qsizetype n) const &
472 { verify(0, n); return sliced(size() - n, n); }
473 [[nodiscard]] QString sliced(qsizetype pos) const &
474 { verify(pos, 0); return sliced(pos, size() - pos); }
475 [[nodiscard]] QString sliced(qsizetype pos, qsizetype n) const &
476 { verify(pos, n); return QString(begin() + pos, n); }
477 [[nodiscard]] QString chopped(qsizetype n) const &
478 { verify(0, n); return sliced(0, size() - n); }
479
480 [[nodiscard]] QString first(qsizetype n) &&
481 {
482 verify(0, n);
483 resize(n); // may detach and allocate memory
484 return std::move(*this);
485 }
486 [[nodiscard]] QString last(qsizetype n) &&
487 { verify(0, n); return sliced_helper(*this, size() - n, n); }
488 [[nodiscard]] QString sliced(qsizetype pos) &&
489 { verify(pos, 0); return sliced_helper(*this, pos, size() - pos); }
490 [[nodiscard]] QString sliced(qsizetype pos, qsizetype n) &&
491 { verify(pos, n); return sliced_helper(*this, pos, n); }
492 [[nodiscard]] QString chopped(qsizetype n) &&
493 { verify(0, n); return std::move(*this).first(size() - n); }
494#endif
495 bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
496 [[nodiscard]] bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
497 { return QtPrivate::startsWith(*this, s, cs); }
498 bool startsWith(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
499 bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
500
501 bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
502 [[nodiscard]] bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
503 { return QtPrivate::endsWith(*this, s, cs); }
504 bool endsWith(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
505 bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
506
507 bool isUpper() const;
508 bool isLower() const;
509
510 [[nodiscard]] QString leftJustified(qsizetype width, QChar fill = u' ', bool trunc = false) const;
511 [[nodiscard]] QString rightJustified(qsizetype width, QChar fill = u' ', bool trunc = false) const;
512
513#if !defined(Q_QDOC)
514 [[nodiscard]] QString toLower() const &
515 { return toLower_helper(*this); }
516 [[nodiscard]] QString toLower() &&
517 { return toLower_helper(*this); }
518 [[nodiscard]] QString toUpper() const &
519 { return toUpper_helper(*this); }
520 [[nodiscard]] QString toUpper() &&
521 { return toUpper_helper(*this); }
522 [[nodiscard]] QString toCaseFolded() const &
523 { return toCaseFolded_helper(*this); }
524 [[nodiscard]] QString toCaseFolded() &&
525 { return toCaseFolded_helper(*this); }
526 [[nodiscard]] QString trimmed() const &
527 { return trimmed_helper(*this); }
528 [[nodiscard]] QString trimmed() &&
529 { return trimmed_helper(*this); }
530 [[nodiscard]] QString simplified() const &
531 { return simplified_helper(*this); }
532 [[nodiscard]] QString simplified() &&
533 { return simplified_helper(*this); }
534#else
535 [[nodiscard]] QString toLower() const;
536 [[nodiscard]] QString toUpper() const;
537 [[nodiscard]] QString toCaseFolded() const;
538 [[nodiscard]] QString trimmed() const;
539 [[nodiscard]] QString simplified() const;
540#endif
541 [[nodiscard]] QString toHtmlEscaped() const;
542
543 QString &insert(qsizetype i, QChar c);
544 QString &insert(qsizetype i, const QChar *uc, qsizetype len);
545 inline QString &insert(qsizetype i, const QString &s) { return insert(i, s.constData(), s.size()); }
546 inline QString &insert(qsizetype i, QStringView v) { return insert(i, v.data(), v.size()); }
547 QString &insert(qsizetype i, QLatin1StringView s);
548 QString &insert(qsizetype i, QUtf8StringView s);
549
550 QString &append(QChar c);
551 QString &append(const QChar *uc, qsizetype len);
552 QString &append(const QString &s);
553 inline QString &append(QStringView v) { return append(v.data(), v.size()); }
554 QString &append(QLatin1StringView s);
555 QString &append(QUtf8StringView s);
556
557 inline QString &prepend(QChar c) { return insert(0, c); }
558 inline QString &prepend(const QChar *uc, qsizetype len) { return insert(0, uc, len); }
559 inline QString &prepend(const QString &s) { return insert(0, s); }
560 inline QString &prepend(QStringView v) { return prepend(v.data(), v.size()); }
561 inline QString &prepend(QLatin1StringView s) { return insert(0, s); }
562 QString &prepend(QUtf8StringView s) { return insert(0, s); }
563
564 QString &assign(QAnyStringView s);
565 inline QString &assign(qsizetype n, QChar c)
566 {
567 Q_ASSERT(n >= 0);
568 return fill(c, n);
569 }
570 template <typename InputIterator, if_compatible_iterator<InputIterator> = true>
571 QString &assign(InputIterator first, InputIterator last)
572 {
573 using V = typename std::iterator_traits<InputIterator>::value_type;
574 constexpr bool IsL1C = std::is_same_v<std::remove_cv_t<V>, QLatin1Char>;
575 constexpr bool IsFwdIt = std::is_convertible_v<
576 typename std::iterator_traits<InputIterator>::iterator_category,
577 std::forward_iterator_tag
578 >;
579
580 if constexpr (is_contiguous_iterator_v<InputIterator>) {
581 const auto p = q20::to_address(first);
582 const auto len = qsizetype(last - first);
583 if constexpr (IsL1C)
584 return assign(QLatin1StringView(reinterpret_cast<const char*>(p), len));
585 else if constexpr (sizeof(V) == 4)
586 return assign_helper(p, len);
587 else
588 return assign(QAnyStringView(p, len));
589 } else if constexpr (sizeof(V) == 4) { // non-contiguous iterator, feed data piecemeal
590 resize(0);
591 if constexpr (IsFwdIt) {
592 const qsizetype requiredCapacity = 2 * std::distance(first, last);
593 reserve(requiredCapacity);
594 }
595 while (first != last) {
596 append(QChar::fromUcs4(*first));
597 ++first;
598 }
599 return *this;
600 } else if constexpr (QtPrivate::IsCompatibleChar8Type<V>::value) {
601 assign_helper_char8(first, last);
602 if (d.constAllocatedCapacity())
603 d.data()[d.size] = u'\0';
604 return *this;
605 } else {
606 d.assign(first, last, [](QChar ch) -> char16_t { return ch.unicode(); });
607 if (d.constAllocatedCapacity())
608 d.data()[d.size] = u'\0';
609 return *this;
610 }
611 }
612
613 inline QString &operator+=(QChar c) { return append(c); }
614
615 inline QString &operator+=(const QString &s) { return append(s); }
616 inline QString &operator+=(QStringView v) { return append(v); }
617 inline QString &operator+=(QLatin1StringView s) { return append(s); }
618 QString &operator+=(QUtf8StringView s) { return append(s); }
619
620#if defined(QT_RESTRICTED_CAST_FROM_ASCII)
621 template <qsizetype N>
622 QString &insert(qsizetype i, const char (&ch)[N]) { return insert(i, QUtf8StringView(ch)); }
623 template <qsizetype N>
624 QString &append(const char (&ch)[N]) { return append(QUtf8StringView(ch)); }
625 template <qsizetype N>
626 QString &prepend(const char (&ch)[N]) { return prepend(QUtf8StringView(ch)); }
627 template <qsizetype N>
628 QString &operator+=(const char (&ch)[N]) { return append(QUtf8StringView(ch)); }
629#endif
630
631 QString &remove(qsizetype i, qsizetype len);
632 QString &remove(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive);
633 QString &remove(QLatin1StringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
634 QString &remove(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
635
636 QString &removeAt(qsizetype pos)
637 { return size_t(pos) < size_t(size()) ? remove(pos, 1) : *this; }
638 QString &removeFirst() { return !isEmpty() ? remove(0, 1) : *this; }
639 QString &removeLast() { return !isEmpty() ? remove(size() - 1, 1) : *this; }
640
641 template <typename Predicate>
642 QString &removeIf(Predicate pred)
643 {
644 removeIf_helper(pred);
645 return *this;
646 }
647
648 QString &replace(qsizetype i, qsizetype len, QChar after);
649 QString &replace(qsizetype i, qsizetype len, const QChar *s, qsizetype slen);
650 QString &replace(qsizetype i, qsizetype len, const QString &after);
651 QString &replace(QChar before, QChar after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
652 QString &replace(const QChar *before, qsizetype blen, const QChar *after, qsizetype alen, Qt::CaseSensitivity cs = Qt::CaseSensitive);
653 QString &replace(QLatin1StringView before, QLatin1StringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
654 QString &replace(QLatin1StringView before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
655 QString &replace(const QString &before, QLatin1StringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
656 QString &replace(const QString &before, const QString &after,
657 Qt::CaseSensitivity cs = Qt::CaseSensitive);
658 QString &replace(QChar c, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
659 QString &replace(QChar c, QLatin1StringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
660#if QT_CONFIG(regularexpression)
661 QString &replace(const QRegularExpression &re, const QString &after);
662 inline QString &remove(const QRegularExpression &re)
663 { return replace(re, QString()); }
664#endif
665
666public:
667 [[nodiscard]]
668 QStringList split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
669 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
670 [[nodiscard]]
671 QStringList split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
672 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
673#ifndef QT_NO_REGULAREXPRESSION
674 [[nodiscard]]
675 QStringList split(const QRegularExpression &sep,
676 Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
677#endif
678
679 template <typename Needle, typename...Flags>
680 [[nodiscard]] inline auto tokenize(Needle &&needle, Flags...flags) const &
681 noexcept(noexcept(qTokenize(std::declval<const QString &>(), std::forward<Needle>(needle), flags...)))
682 -> decltype(qTokenize(*this, std::forward<Needle>(needle), flags...))
683 { return qTokenize(qToStringViewIgnoringNull(*this), std::forward<Needle>(needle), flags...); }
684
685 template <typename Needle, typename...Flags>
686 [[nodiscard]] inline auto tokenize(Needle &&needle, Flags...flags) const &&
687 noexcept(noexcept(qTokenize(std::declval<const QString>(), std::forward<Needle>(needle), flags...)))
688 -> decltype(qTokenize(std::move(*this), std::forward<Needle>(needle), flags...))
689 { return qTokenize(std::move(*this), std::forward<Needle>(needle), flags...); }
690
691 template <typename Needle, typename...Flags>
692 [[nodiscard]] inline auto tokenize(Needle &&needle, Flags...flags) &&
693 noexcept(noexcept(qTokenize(std::declval<QString>(), std::forward<Needle>(needle), flags...)))
694 -> decltype(qTokenize(std::move(*this), std::forward<Needle>(needle), flags...))
695 { return qTokenize(std::move(*this), std::forward<Needle>(needle), flags...); }
696
697
698 enum NormalizationForm {
699 NormalizationForm_D,
700 NormalizationForm_C,
701 NormalizationForm_KD,
702 NormalizationForm_KC
703 };
704 [[nodiscard]] QString normalized(NormalizationForm mode, QChar::UnicodeVersion version = QChar::Unicode_Unassigned) const;
705
706 [[nodiscard]] QString repeated(qsizetype times) const;
707
708 const ushort *utf16() const; // ### Qt 7 char16_t
709 [[nodiscard]] QString nullTerminated() const &
710 {
711 // ensure '\0'-termination for ::fromRawData strings
712 if (!d->isMutable())
713 return QString{constData(), size()};
714 return *this;
715 }
716
717 [[nodiscard]] QString nullTerminated() &&
718 {
719 // ensure '\0'-termination for ::fromRawData strings
720 if (!d->isMutable())
721 return QString{constData(), size()};
722 return std::move(*this);
723 }
724
725 QString &nullTerminate()
726 {
727 // ensure '\0'-termination for ::fromRawData strings
728 if (!d->isMutable())
729 *this = QString{constData(), size()};
730 return *this;
731 }
732
733#if !defined(Q_QDOC)
734 [[nodiscard]] QByteArray toLatin1() const &
735 { return toLatin1_helper(*this); }
736 [[nodiscard]] QByteArray toLatin1() &&
737 { return toLatin1_helper_inplace(*this); }
738 [[nodiscard]] QByteArray toUtf8() const &
739 { return toUtf8_helper(*this); }
740 [[nodiscard]] QByteArray toUtf8() &&
741 { return toUtf8_helper(*this); }
742 [[nodiscard]] QByteArray toLocal8Bit() const &
743 { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
744 [[nodiscard]] QByteArray toLocal8Bit() &&
745 { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
746#else
747 [[nodiscard]] QByteArray toLatin1() const;
748 [[nodiscard]] QByteArray toUtf8() const;
749 [[nodiscard]] QByteArray toLocal8Bit() const;
750#endif
751 [[nodiscard]] QList<uint> toUcs4() const; // ### Qt 7 char32_t
752
753 // note - this are all inline so we can benefit from strlen() compile time optimizations
754 static QString fromLatin1(QByteArrayView ba);
755 Q_WEAK_OVERLOAD
756 static inline QString fromLatin1(const QByteArray &ba) { return fromLatin1(QByteArrayView(ba)); }
757 static inline QString fromLatin1(const char *str, qsizetype size)
758 {
759 return fromLatin1(QByteArrayView(str, !str || size < 0 ? qstrlen(str) : size));
760 }
761 static QString fromUtf8(QByteArrayView utf8);
762 Q_WEAK_OVERLOAD
763 static inline QString fromUtf8(const QByteArray &ba) { return fromUtf8(QByteArrayView(ba)); }
764 static inline QString fromUtf8(const char *utf8, qsizetype size)
765 {
766 return fromUtf8(QByteArrayView(utf8, !utf8 || size < 0 ? qstrlen(utf8) : size));
767 }
768#if defined(__cpp_char8_t) || defined(Q_QDOC)
769 Q_WEAK_OVERLOAD
770 static inline QString fromUtf8(const char8_t *str)
771 { return fromUtf8(reinterpret_cast<const char *>(str)); }
772 Q_WEAK_OVERLOAD
773 static inline QString fromUtf8(const char8_t *str, qsizetype size)
774 { return fromUtf8(reinterpret_cast<const char *>(str), size); }
775#endif
776 static QString fromLocal8Bit(QByteArrayView ba);
777 Q_WEAK_OVERLOAD
778 static inline QString fromLocal8Bit(const QByteArray &ba) { return fromLocal8Bit(QByteArrayView(ba)); }
779 static inline QString fromLocal8Bit(const char *str, qsizetype size)
780 {
781 return fromLocal8Bit(QByteArrayView(str, !str || size < 0 ? qstrlen(str) : size));
782 }
783 static QString fromUtf16(const char16_t *, qsizetype size = -1);
784 static QString fromUcs4(const char32_t *, qsizetype size = -1);
785 static QString fromRawData(const char16_t *unicode, qsizetype size)
786 {
787 return QString(DataPointer::fromRawData(unicode, size));
788 }
789 QT_CORE_INLINE_SINCE(6, 10)
790 static QString fromRawData(const QChar *, qsizetype size);
791
792#if QT_DEPRECATED_SINCE(6, 0)
793 QT_DEPRECATED_VERSION_X_6_0("Use char16_t* overload.")
794 static QString fromUtf16(const ushort *str, qsizetype size = -1)
795 { return fromUtf16(reinterpret_cast<const char16_t *>(str), size); }
796 QT_DEPRECATED_VERSION_X_6_0("Use char32_t* overload.")
797 static QString fromUcs4(const uint *str, qsizetype size = -1)
798 { return fromUcs4(reinterpret_cast<const char32_t *>(str), size); }
799#endif
800
801 inline qsizetype toWCharArray(wchar_t *array) const;
802 [[nodiscard]] static inline QString fromWCharArray(const wchar_t *string, qsizetype size = -1);
803
804 QString &setRawData(const QChar *unicode, qsizetype size);
805 QString &setUnicode(const QChar *unicode, qsizetype size);
806 Q_WEAK_OVERLOAD
807 QString &setUnicode(const char16_t *utf16, qsizetype size)
808 { return setUnicode(reinterpret_cast<const QChar *>(utf16), size); }
809 QString &setUtf16(const char16_t *utf16, qsizetype size)
810 { return setUnicode(reinterpret_cast<const QChar *>(utf16), size); }
811
812#if !QT_CORE_REMOVED_SINCE(6, 9)
813 Q_WEAK_OVERLOAD
814#endif
815 QString &setUtf16(const ushort *autf16, qsizetype asize)
816 { return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
817
818 int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
819 int compare(QLatin1StringView other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
820 inline int compare(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
821 int compare(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
822 { return compare(QStringView{&ch, 1}, cs); }
823
824 static inline int compare(const QString &s1, const QString &s2,
825 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
826 { return s1.compare(s2, cs); }
827
828 static inline int compare(const QString &s1, QLatin1StringView s2,
829 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
830 { return s1.compare(s2, cs); }
831 static inline int compare(QLatin1StringView s1, const QString &s2,
832 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
833 { return -s2.compare(s1, cs); }
834 static int compare(const QString &s1, QStringView s2, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
835 { return s1.compare(s2, cs); }
836 static int compare(QStringView s1, const QString &s2, Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
837 { return -s2.compare(s1, cs); }
838
839 int localeAwareCompare(const QString& s) const;
840 inline int localeAwareCompare(QStringView s) const;
841 static int localeAwareCompare(const QString& s1, const QString& s2)
842 { return s1.localeAwareCompare(s2); }
843
844 static inline int localeAwareCompare(QStringView s1, QStringView s2);
845
846 short toShort(bool *ok=nullptr, int base=10) const
847 { return toIntegral_helper<short>(*this, ok, base); }
848 ushort toUShort(bool *ok=nullptr, int base=10) const
849 { return toIntegral_helper<ushort>(*this, ok, base); }
850 int toInt(bool *ok=nullptr, int base=10) const
851 { return toIntegral_helper<int>(*this, ok, base); }
852 uint toUInt(bool *ok=nullptr, int base=10) const
853 { return toIntegral_helper<uint>(*this, ok, base); }
854 long toLong(bool *ok=nullptr, int base=10) const
855 { return toIntegral_helper<long>(*this, ok, base); }
856 ulong toULong(bool *ok=nullptr, int base=10) const
857 { return toIntegral_helper<ulong>(*this, ok, base); }
858 QT_CORE_INLINE_SINCE(6, 5)
859 qlonglong toLongLong(bool *ok=nullptr, int base=10) const;
860 QT_CORE_INLINE_SINCE(6, 5)
861 qulonglong toULongLong(bool *ok=nullptr, int base=10) const;
862 float toFloat(bool *ok=nullptr) const;
863 double toDouble(bool *ok=nullptr) const;
864
865 inline QString &setNum(short, int base=10);
866 inline QString &setNum(ushort, int base=10);
867 inline QString &setNum(int, int base=10);
868 inline QString &setNum(uint, int base=10);
869 inline QString &setNum(long, int base=10);
870 inline QString &setNum(ulong, int base=10);
871 QString &setNum(qlonglong, int base=10);
872 QString &setNum(qulonglong, int base=10);
873 inline QString &setNum(float, char format='g', int precision=6);
874 QString &setNum(double, char format='g', int precision=6);
875
876 static QString number(int, int base=10);
877 static QString number(uint, int base=10);
878 static QString number(long, int base=10);
879 static QString number(ulong, int base=10);
880 static QString number(qlonglong, int base=10);
881 static QString number(qulonglong, int base=10);
882 static QString number(double, char format='g', int precision=6);
883
884 friend bool comparesEqual(const QString &s1, const QString &s2) noexcept
885 { return comparesEqual(QStringView(s1), QStringView(s2)); }
886 friend Qt::strong_ordering compareThreeWay(const QString &s1, const QString &s2) noexcept
887 { return compareThreeWay(QStringView(s1), QStringView(s2)); }
888 Q_DECLARE_STRONGLY_ORDERED(QString)
889
890 Q_WEAK_OVERLOAD
891 friend bool comparesEqual(const QString &s1, QUtf8StringView s2) noexcept
892 { return QtPrivate::equalStrings(s1, s2); }
893 Q_WEAK_OVERLOAD
894 friend Qt::strong_ordering compareThreeWay(const QString &s1, QUtf8StringView s2) noexcept
895 {
896 const int res = QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive);
897 return Qt::compareThreeWay(res, 0);
898 }
899 Q_DECLARE_STRONGLY_ORDERED(QString, QUtf8StringView, Q_WEAK_OVERLOAD)
900
901#ifdef __cpp_char8_t
902 friend bool comparesEqual(const QString &s1, const char8_t *s2) noexcept
903 { return comparesEqual(s1, QUtf8StringView(s2)); }
904 friend Qt::strong_ordering compareThreeWay(const QString &s1, const char8_t *s2) noexcept
905 { return compareThreeWay(s1, QUtf8StringView(s2)); }
906 Q_DECLARE_STRONGLY_ORDERED(QString, const char8_t *)
907#endif // __cpp_char8_t
908
909 friend bool comparesEqual(const QString &s1, QLatin1StringView s2) noexcept
910 { return (s1.size() == s2.size()) && QtPrivate::equalStrings(s1, s2); }
911 friend Qt::strong_ordering
912 compareThreeWay(const QString &s1, QLatin1StringView s2) noexcept
913 {
914 const int res = QtPrivate::compareStrings(s1, s2, Qt::CaseSensitive);
915 return Qt::compareThreeWay(res, 0);
916 }
917 Q_DECLARE_STRONGLY_ORDERED(QString, QLatin1StringView)
918
919 // Check isEmpty() instead of isNull() for backwards compatibility.
920 friend bool comparesEqual(const QString &s1, std::nullptr_t) noexcept
921 { return s1.isEmpty(); }
922 friend Qt::strong_ordering compareThreeWay(const QString &s1, std::nullptr_t) noexcept
923 { return s1.isEmpty() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
924 Q_DECLARE_STRONGLY_ORDERED(QString, std::nullptr_t)
925
926 friend bool comparesEqual(const QString &s1, const char16_t *s2) noexcept
927 { return comparesEqual(s1, QStringView(s2)); }
928 friend Qt::strong_ordering compareThreeWay(const QString &s1, const char16_t *s2) noexcept
929 { return compareThreeWay(s1, QStringView(s2)); }
930 Q_DECLARE_STRONGLY_ORDERED(QString, const char16_t *)
931
932 // QChar <> QString
933 friend bool comparesEqual(const QString &lhs, QChar rhs) noexcept
934 { return lhs.size() == 1 && rhs == lhs.front(); }
935 friend Qt::strong_ordering compareThreeWay(const QString &lhs, QChar rhs) noexcept
936 {
937 const int res = compare_helper(lhs.data(), lhs.size(), &rhs, 1);
938 return Qt::compareThreeWay(res, 0);
939 }
940 Q_DECLARE_STRONGLY_ORDERED(QString, QChar)
941
942 // ASCII compatibility
943#if defined(QT_RESTRICTED_CAST_FROM_ASCII)
944 template <qsizetype N>
945 inline QString(const char (&ch)[N])
946 : QString(fromUtf8(ch))
947 {}
948 template <qsizetype N>
949 QString(char (&)[N]) = delete;
950 template <qsizetype N>
951 inline QString &operator=(const char (&ch)[N])
952 { return (*this = fromUtf8(ch, N - 1)); }
953 template <qsizetype N>
954 QString &operator=(char (&)[N]) = delete;
955#endif
956#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
957 QT_ASCII_CAST_WARN inline QString(const char *ch)
958 : QString(fromUtf8(ch))
959 {}
960 QT_ASCII_CAST_WARN inline QString(const QByteArray &a)
961 : QString(fromUtf8(a))
962 {}
963 QT_ASCII_CAST_WARN inline QString &operator=(const char *ch)
964 {
965 if (!ch) {
966 clear();
967 return *this;
968 }
969 return assign(ch);
970 }
971 QT_ASCII_CAST_WARN inline QString &operator=(const QByteArray &a)
972 {
973 if (a.isNull()) {
974 clear();
975 return *this;
976 }
977 return assign(a);
978 }
979 // these are needed, so it compiles with STL support enabled
980 QT_ASCII_CAST_WARN inline QString &prepend(const char *s)
981 { return prepend(QUtf8StringView(s)); }
982 QT_ASCII_CAST_WARN inline QString &prepend(const QByteArray &s)
983 { return prepend(QUtf8StringView(s)); }
984 QT_ASCII_CAST_WARN inline QString &append(const char *s)
985 { return append(QUtf8StringView(s)); }
986 QT_ASCII_CAST_WARN inline QString &append(const QByteArray &s)
987 { return append(QUtf8StringView(s)); }
988 QT_ASCII_CAST_WARN inline QString &insert(qsizetype i, const char *s)
989 { return insert(i, QUtf8StringView(s)); }
990 QT_ASCII_CAST_WARN inline QString &insert(qsizetype i, const QByteArray &s)
991 { return insert(i, QUtf8StringView(s)); }
992 QT_ASCII_CAST_WARN inline QString &operator+=(const char *s)
993 { return append(QUtf8StringView(s)); }
994 QT_ASCII_CAST_WARN inline QString &operator+=(const QByteArray &s)
995 { return append(QUtf8StringView(s)); }
996
997#if QT_CORE_REMOVED_SINCE(6, 8)
998 QT_ASCII_CAST_WARN inline bool operator==(const char *s) const;
999 QT_ASCII_CAST_WARN inline bool operator!=(const char *s) const;
1000 QT_ASCII_CAST_WARN inline bool operator<(const char *s) const;
1001 QT_ASCII_CAST_WARN inline bool operator<=(const char *s) const;
1002 QT_ASCII_CAST_WARN inline bool operator>(const char *s) const;
1003 QT_ASCII_CAST_WARN inline bool operator>=(const char *s) const;
1004
1005 QT_ASCII_CAST_WARN inline bool operator==(const QByteArray &s) const;
1006 QT_ASCII_CAST_WARN inline bool operator!=(const QByteArray &s) const;
1007 QT_ASCII_CAST_WARN inline bool operator<(const QByteArray &s) const;
1008 QT_ASCII_CAST_WARN inline bool operator>(const QByteArray &s) const;
1009 QT_ASCII_CAST_WARN inline bool operator<=(const QByteArray &s) const;
1010 QT_ASCII_CAST_WARN inline bool operator>=(const QByteArray &s) const;
1011#else
1012 friend bool comparesEqual(const QString &lhs, QByteArrayView rhs) noexcept
1013 {
1014 return QString::compare_helper(lhs.constData(), lhs.size(),
1015 rhs.constData(), rhs.size()) == 0;
1016 }
1017 friend Qt::strong_ordering
1018 compareThreeWay(const QString &lhs, QByteArrayView rhs) noexcept
1019 {
1020 const int res = QString::compare_helper(lhs.constData(), lhs.size(),
1021 rhs.constData(), rhs.size());
1022 return Qt::compareThreeWay(res, 0);
1023 }
1024 Q_DECLARE_STRONGLY_ORDERED(QString, QByteArrayView, QT_ASCII_CAST_WARN)
1025
1026 friend bool comparesEqual(const QString &lhs, const QByteArray &rhs) noexcept
1027 { return comparesEqual(lhs, QByteArrayView(rhs)); }
1028 friend Qt::strong_ordering
1029 compareThreeWay(const QString &lhs, const QByteArray &rhs) noexcept
1030 {
1031 return compareThreeWay(lhs, QByteArrayView(rhs));
1032 }
1033 Q_DECLARE_STRONGLY_ORDERED(QString, QByteArray, QT_ASCII_CAST_WARN)
1034
1035 friend bool comparesEqual(const QString &lhs, const char *rhs) noexcept
1036 { return comparesEqual(lhs, QByteArrayView(rhs)); }
1037 friend Qt::strong_ordering
1038 compareThreeWay(const QString &lhs, const char *rhs) noexcept
1039 {
1040 return compareThreeWay(lhs, QByteArrayView(rhs));
1041 }
1042 Q_DECLARE_STRONGLY_ORDERED(QString, const char *, QT_ASCII_CAST_WARN)
1043#endif // QT_CORE_REMOVED_SINCE(6, 8)
1044
1045#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1046
1047 typedef QChar *iterator;
1048 typedef const QChar *const_iterator;
1049 typedef iterator Iterator;
1050 typedef const_iterator ConstIterator;
1051 typedef std::reverse_iterator<iterator> reverse_iterator;
1052 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1053 inline iterator begin();
1054 inline const_iterator begin() const;
1055 inline const_iterator cbegin() const;
1056 inline const_iterator constBegin() const;
1057 inline iterator end();
1058 inline const_iterator end() const;
1059 inline const_iterator cend() const;
1060 inline const_iterator constEnd() const;
1061 reverse_iterator rbegin() { return reverse_iterator(end()); }
1062 reverse_iterator rend() { return reverse_iterator(begin()); }
1063 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
1064 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
1065 const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
1066 const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
1067
1068 // STL compatibility
1069 typedef qsizetype size_type;
1070 typedef qptrdiff difference_type;
1071 typedef const QChar & const_reference;
1072 typedef QChar & reference;
1073 typedef QChar *pointer;
1074 typedef const QChar *const_pointer;
1075 typedef QChar value_type;
1076 inline void push_back(QChar c) { append(c); }
1077 inline void push_back(const QString &s) { append(s); }
1078 inline void push_front(QChar c) { prepend(c); }
1079 inline void push_front(const QString &s) { prepend(s); }
1080 void shrink_to_fit() { squeeze(); }
1081 iterator erase(const_iterator first, const_iterator last);
1082 inline iterator erase(const_iterator it) { return erase(it, it + 1); }
1083 constexpr qsizetype max_size() const noexcept
1084 {
1085 return maxSize();
1086 }
1087
1088 static inline QString fromStdString(const std::string &s);
1089 std::string toStdString() const;
1090 static inline QString fromStdWString(const std::wstring &s);
1091 inline std::wstring toStdWString() const;
1092
1093 static inline QString fromStdU16String(const std::u16string &s);
1094 inline std::u16string toStdU16String() const;
1095 static inline QString fromStdU32String(const std::u32string &s);
1096 inline std::u32string toStdU32String() const;
1097
1098 Q_IMPLICIT inline operator std::u16string_view() const noexcept;
1099
1100#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
1101 static QString fromCFString(CFStringRef string);
1102 CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
1103 static QString fromNSString(const NSString *string);
1104 NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
1105#endif
1106
1107#if defined(Q_OS_WASM) || defined(Q_QDOC)
1108 static QString fromEcmaString(emscripten::val jsString);
1109 emscripten::val toEcmaString() const;
1110#endif
1111
1112 constexpr bool isNull() const { return d.isNull(); }
1113
1114 bool isRightToLeft() const;
1115 [[nodiscard]] bool isValidUtf16() const noexcept
1116 { return QStringView(*this).isValidUtf16(); }
1117
1118 QString(qsizetype size, Qt::Initialization);
1119 explicit QString(DataPointer &&dd) : d(std::move(dd)) {}
1120
1121private:
1122#if defined(QT_NO_CAST_FROM_ASCII)
1123#define QSTRING_DECL_DELETED_ASCII_OP Q_DECL_EQ_DELETE_X("This function is not available under QT_NO_CAST_FROM_ASCII")
1124 QString &operator+=(const char *s) QSTRING_DECL_DELETED_ASCII_OP;
1125 QString &operator+=(const QByteArray &s) QSTRING_DECL_DELETED_ASCII_OP;
1126 QString(const char *ch) QSTRING_DECL_DELETED_ASCII_OP;
1127 QString(const QByteArray &a) QSTRING_DECL_DELETED_ASCII_OP;
1128 QString &operator=(const char *ch) QSTRING_DECL_DELETED_ASCII_OP;
1129 QString &operator=(const QByteArray &a) QSTRING_DECL_DELETED_ASCII_OP;
1130#undef QSTRING_DECL_DELETED_ASCII_OP
1131#endif
1132
1133 DataPointer d;
1134 static const char16_t _empty;
1135
1136 void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
1137 void reallocGrowData(qsizetype n);
1138 // ### remove once QAnyStringView supports UTF-32:
1139 QString &assign_helper(const char32_t *data, qsizetype len);
1140 // Defined in qstringconverter.h
1141 template <typename InputIterator>
1142 void assign_helper_char8(InputIterator first, InputIterator last);
1143 static int compare_helper(const QChar *data1, qsizetype length1,
1144 const QChar *data2, qsizetype length2,
1145 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
1146 static int compare_helper(const QChar *data1, qsizetype length1,
1147 const char *data2, qsizetype length2,
1148 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
1149 static int localeAwareCompare_helper(const QChar *data1, qsizetype length1,
1150 const QChar *data2, qsizetype length2);
1151 static QString sliced_helper(QString &str, qsizetype pos, qsizetype n);
1152 static QString toLower_helper(const QString &str);
1153 static QString toLower_helper(QString &str);
1154 static QString toUpper_helper(const QString &str);
1155 static QString toUpper_helper(QString &str);
1156 static QString toCaseFolded_helper(const QString &str);
1157 static QString toCaseFolded_helper(QString &str);
1158 static QString trimmed_helper(const QString &str);
1159 static QString trimmed_helper(QString &str);
1160 static QString simplified_helper(const QString &str);
1161 static QString simplified_helper(QString &str);
1162 static QByteArray toLatin1_helper(const QString &);
1163 static QByteArray toLatin1_helper_inplace(QString &);
1164 static QByteArray toUtf8_helper(const QString &);
1165 static QByteArray toLocal8Bit_helper(const QChar *data, qsizetype size);
1166#if QT_CORE_REMOVED_SINCE(6, 6)
1167 static qsizetype toUcs4_helper(const ushort *uc, qsizetype length, uint *out);
1168#endif
1169 static qsizetype toUcs4_helper(const char16_t *uc, qsizetype length, char32_t *out);
1170 static qlonglong toIntegral_helper(QStringView string, bool *ok, int base);
1171 static qulonglong toIntegral_helper(QStringView string, bool *ok, uint base);
1172 template <typename Predicate>
1173 qsizetype removeIf_helper(Predicate pred)
1174 {
1175 const qsizetype result = d->eraseIf(pred);
1176 if (result > 0)
1177 d.data()[d.size] = u'\0';
1178 return result;
1179 }
1180
1181 friend class QStringView;
1182 friend class QByteArray;
1183 friend struct QAbstractConcatenable;
1184 template <typename T> friend qsizetype erase(QString &s, const T &t);
1185 template <typename Predicate> friend qsizetype erase_if(QString &s, Predicate pred);
1186
1187 template <typename T> static
1188 T toIntegral_helper(QStringView string, bool *ok, int base)
1189 {
1190 using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
1191 using Int32 = typename std::conditional<std::is_unsigned<T>::value, uint, int>::type;
1192
1193 // we select the right overload by casting base to int or uint
1194 Int64 val = toIntegral_helper(string, ok, Int32(base));
1195 if (T(val) != val) {
1196 if (ok)
1197 *ok = false;
1198 val = 0;
1199 }
1200 return T(val);
1201 }
1202
1203 Q_ALWAYS_INLINE constexpr void verify([[maybe_unused]] qsizetype pos = 0,
1204 [[maybe_unused]] qsizetype n = 1) const
1205 {
1206 Q_ASSERT(pos >= 0);
1207 Q_ASSERT(pos <= d.size);
1208 Q_ASSERT(n >= 0);
1209 Q_ASSERT(n <= d.size - pos);
1210 }
1211
1212public:
1213 inline DataPointer &data_ptr() { return d; }
1214 inline const DataPointer &data_ptr() const { return d; }
1215};
1216
1217//
1218// QLatin1StringView inline members that require QUtf8StringView:
1219//
1220
1221int QLatin1StringView::compare(QUtf8StringView other, Qt::CaseSensitivity cs) const noexcept
1222{ return QtPrivate::compareStrings(*this, other, cs); }
1223
1224//
1225// QLatin1StringView inline members that require QString:
1226//
1227
1228QString QLatin1StringView::toString() const { return *this; }
1229
1230//
1231// QStringView inline members that require QUtf8StringView:
1232//
1233
1234int QStringView::compare(QUtf8StringView other, Qt::CaseSensitivity cs) const noexcept
1235{ return QtPrivate::compareStrings(*this, other, cs); }
1236
1237//
1238// QStringView inline members that require QString:
1239//
1240
1241QString QStringView::toString() const
1242{ return QString(*this); }
1243
1244qint64 QStringView::toLongLong(bool *ok, int base) const
1245{ return QString::toIntegral_helper<qint64>(*this, ok, base); }
1246quint64 QStringView::toULongLong(bool *ok, int base) const
1247{ return QString::toIntegral_helper<quint64>(*this, ok, base); }
1248long QStringView::toLong(bool *ok, int base) const
1249{ return QString::toIntegral_helper<long>(*this, ok, base); }
1250ulong QStringView::toULong(bool *ok, int base) const
1251{ return QString::toIntegral_helper<ulong>(*this, ok, base); }
1252int QStringView::toInt(bool *ok, int base) const
1253{ return QString::toIntegral_helper<int>(*this, ok, base); }
1254uint QStringView::toUInt(bool *ok, int base) const
1255{ return QString::toIntegral_helper<uint>(*this, ok, base); }
1256short QStringView::toShort(bool *ok, int base) const
1257{ return QString::toIntegral_helper<short>(*this, ok, base); }
1258ushort QStringView::toUShort(bool *ok, int base) const
1259{ return QString::toIntegral_helper<ushort>(*this, ok, base); }
1260
1261//
1262// QUtf8StringView inline members that require QStringView:
1263//
1264
1265template <bool UseChar8T>
1266int QBasicUtf8StringView<UseChar8T>::compare(QChar other, Qt::CaseSensitivity cs) const noexcept
1267{
1268 return QtPrivate::compareStrings(*this, QStringView(&other, 1), cs);
1269}
1270
1271template <bool UseChar8T>
1272int QBasicUtf8StringView<UseChar8T>::compare(QStringView other, Qt::CaseSensitivity cs) const noexcept
1273{
1274 return QtPrivate::compareStrings(*this, other, cs);
1275}
1276
1277template <bool UseChar8T>
1278[[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(QChar other) const noexcept
1279{
1280 return QtPrivate::equalStrings(*this, QStringView(&other, 1));
1281}
1282
1283template <bool UseChar8T>
1284[[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(QStringView other) const noexcept
1285{
1286 return QtPrivate::equalStrings(*this, other);
1287}
1288
1289//
1290// QUtf8StringView inline members that require QString, QL1SV or QBA:
1291//
1292
1293template <bool UseChar8T>
1294QString QBasicUtf8StringView<UseChar8T>::toString() const
1295{
1296 return QString::fromUtf8(data(), size());
1297}
1298
1299template<bool UseChar8T>
1300[[nodiscard]] int QBasicUtf8StringView<UseChar8T>::compare(QLatin1StringView other,
1301 Qt::CaseSensitivity cs) const noexcept
1302{
1303 return QtPrivate::compareStrings(*this, other, cs);
1304}
1305
1306template<bool UseChar8T>
1307[[nodiscard]] int QBasicUtf8StringView<UseChar8T>::compare(const QByteArray &other,
1308 Qt::CaseSensitivity cs) const noexcept
1309{
1310 return QtPrivate::compareStrings(*this,
1311 QBasicUtf8StringView<UseChar8T>(other.data(), other.size()),
1312 cs);
1313}
1314
1315template <bool UseChar8T>
1316[[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(QLatin1StringView other) const noexcept
1317{
1318 return QtPrivate::equalStrings(*this, other);
1319}
1320
1321template <bool UseChar8T>
1322[[nodiscard]] bool QBasicUtf8StringView<UseChar8T>::equal(const QByteArray &other) const noexcept
1323{
1324 return size() == other.size()
1325 && QtPrivate::equalStrings(*this, QBasicUtf8StringView<UseChar8T>(other.data(),
1326 other.size()));
1327}
1328
1329//
1330// QAnyStringView inline members that require QString:
1331//
1332
1333QAnyStringView::QAnyStringView(const QByteArray &str) noexcept
1334 : QAnyStringView{str.begin(), str.size()} {}
1335QAnyStringView::QAnyStringView(const QString &str) noexcept
1336 : QAnyStringView{str.begin(), str.size()} {}
1337
1338QString QAnyStringView::toString() const
1339{ return QtPrivate::convertToQString(*this); }
1340
1341//
1342// QString inline members
1343//
1344QString::QString(QLatin1StringView latin1)
1345 : QString{QString::fromLatin1(latin1.data(), latin1.size())} {}
1346const QChar QString::at(qsizetype i) const
1347{ verify(i, 1); return QChar(d.data()[i]); }
1348const QChar QString::operator[](qsizetype i) const
1349{ verify(i, 1); return QChar(d.data()[i]); }
1350const QChar *QString::unicode() const
1351{ return data(); }
1352const QChar *QString::data() const
1353{
1354#if QT5_NULL_STRINGS == 1
1355 return reinterpret_cast<const QChar *>(d.data() ? d.data() : &_empty);
1356#else
1357 return reinterpret_cast<const QChar *>(d.data());
1358#endif
1359}
1360QChar *QString::data()
1361{
1362 detach();
1363 Q_ASSERT(d.data());
1364 return reinterpret_cast<QChar *>(d.data());
1365}
1366const QChar *QString::constData() const
1367{ return data(); }
1368void QString::detach()
1369{ if (d.needsDetach()) reallocData(d.size, QArrayData::KeepSize); }
1370bool QString::isDetached() const
1371{ return !d.isShared(); }
1372void QString::clear()
1373{ if (!isNull()) *this = QString(); }
1374QString::QString(const QString &other) noexcept : d(other.d)
1375{ }
1376qsizetype QString::capacity() const { return qsizetype(d.constAllocatedCapacity()); }
1377QString &QString::setNum(short n, int base)
1378{ return setNum(qlonglong(n), base); }
1379QString &QString::setNum(ushort n, int base)
1380{ return setNum(qulonglong(n), base); }
1381QString &QString::setNum(int n, int base)
1382{ return setNum(qlonglong(n), base); }
1383QString &QString::setNum(uint n, int base)
1384{ return setNum(qulonglong(n), base); }
1385QString &QString::setNum(long n, int base)
1386{ return setNum(qlonglong(n), base); }
1387QString &QString::setNum(ulong n, int base)
1388{ return setNum(qulonglong(n), base); }
1389QString &QString::setNum(float n, char f, int prec)
1390{ return setNum(double(n),f,prec); }
1391#if QT_CORE_REMOVED_SINCE(6, 9)
1392QString QString::arg(int a, int fieldWidth, int base, QChar fillChar) const
1393{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
1394QString QString::arg(uint a, int fieldWidth, int base, QChar fillChar) const
1395{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
1396QString QString::arg(long a, int fieldWidth, int base, QChar fillChar) const
1397{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
1398QString QString::arg(ulong a, int fieldWidth, int base, QChar fillChar) const
1399{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
1400QString QString::arg(short a, int fieldWidth, int base, QChar fillChar) const
1401{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
1402QString QString::arg(ushort a, int fieldWidth, int base, QChar fillChar) const
1403{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
1404#endif // QT_CORE_REMOVED_SINCE
1405
1406QString QString::section(QChar asep, qsizetype astart, qsizetype aend, SectionFlags aflags) const
1407{ return section(QString(asep), astart, aend, aflags); }
1408
1409QT_WARNING_PUSH
1410QT_WARNING_DISABLE_MSVC(4127) // "conditional expression is constant"
1411QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable"
1412
1413qsizetype QString::toWCharArray(wchar_t *array) const
1414{
1415 return qToStringViewIgnoringNull(*this).toWCharArray(array);
1416}
1417
1418qsizetype QStringView::toWCharArray(wchar_t *array) const
1419{
1420 if (sizeof(wchar_t) == sizeof(QChar)) {
1421 if (auto src = data())
1422 memcpy(array, src, sizeof(QChar) * size());
1423 return size();
1424 } else {
1425 return QString::toUcs4_helper(utf16(), size(), reinterpret_cast<char32_t *>(array));
1426 }
1427}
1428
1430
1431QString QString::fromWCharArray(const wchar_t *string, qsizetype size)
1432{
1433 if constexpr (sizeof(wchar_t) == sizeof(QChar)) {
1434 return QString(reinterpret_cast<const QChar *>(string), size);
1435 } else {
1436#ifdef QT_BOOTSTRAPPED
1437 Q_UNREACHABLE_RETURN(QString());
1438#else
1439 return fromUcs4(reinterpret_cast<const char32_t *>(string), size);
1440#endif
1441 }
1442}
1443
1444constexpr QString::QString() noexcept {}
1445QString::~QString() {}
1446
1447void QString::reserve(qsizetype asize)
1448{
1449 if (d.needsDetach() || asize >= capacity() - d.freeSpaceAtBegin())
1450 reallocData(qMax(asize, size()), QArrayData::KeepSize);
1451 if (d.constAllocatedCapacity())
1452 d.setFlag(Data::CapacityReserved);
1453}
1454
1455void QString::squeeze()
1456{
1457 if (!d.isMutable())
1458 return;
1459 if (d.needsDetach() || size() < capacity())
1460 reallocData(d.size, QArrayData::KeepSize);
1461 if (d.constAllocatedCapacity())
1462 d.clearFlag(Data::CapacityReserved);
1463}
1464
1465QChar &QString::operator[](qsizetype i)
1466{ verify(i, 1); return data()[i]; }
1467QChar &QString::front() { return operator[](0); }
1468QChar &QString::back() { return operator[](size() - 1); }
1469QString::iterator QString::begin()
1470{ detach(); return reinterpret_cast<QChar*>(d.data()); }
1471QString::const_iterator QString::begin() const
1472{ return reinterpret_cast<const QChar*>(d.data()); }
1473QString::const_iterator QString::cbegin() const
1474{ return reinterpret_cast<const QChar*>(d.data()); }
1475QString::const_iterator QString::constBegin() const
1476{ return reinterpret_cast<const QChar*>(d.data()); }
1477QString::iterator QString::end()
1478{ detach(); return reinterpret_cast<QChar*>(d.data() + d.size); }
1479QString::const_iterator QString::end() const
1480{ return reinterpret_cast<const QChar*>(d.data() + d.size); }
1481QString::const_iterator QString::cend() const
1482{ return reinterpret_cast<const QChar*>(d.data() + d.size); }
1483QString::const_iterator QString::constEnd() const
1484{ return reinterpret_cast<const QChar*>(d.data() + d.size); }
1485bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
1486{ return indexOf(s, 0, cs) != -1; }
1487bool QString::contains(QLatin1StringView s, Qt::CaseSensitivity cs) const
1488{ return indexOf(s, 0, cs) != -1; }
1489bool QString::contains(QChar c, Qt::CaseSensitivity cs) const
1490{ return indexOf(c, 0, cs) != -1; }
1491bool QString::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
1492{ return indexOf(s, 0, cs) != -1; }
1493
1494#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1495#if QT_CORE_REMOVED_SINCE(6, 8)
1496bool QString::operator==(const char *s) const
1497{ return QString::compare_helper(constData(), size(), s, -1) == 0; }
1498bool QString::operator!=(const char *s) const
1499{ return QString::compare_helper(constData(), size(), s, -1) != 0; }
1500bool QString::operator<(const char *s) const
1501{ return QString::compare_helper(constData(), size(), s, -1) < 0; }
1502bool QString::operator>(const char *s) const
1503{ return QString::compare_helper(constData(), size(), s, -1) > 0; }
1504bool QString::operator<=(const char *s) const
1505{ return QString::compare_helper(constData(), size(), s, -1) <= 0; }
1506bool QString::operator>=(const char *s) const
1507{ return QString::compare_helper(constData(), size(), s, -1) >= 0; }
1508
1509QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const
1510{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) == 0; }
1511QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const
1512{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) != 0; }
1513QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const
1514{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; }
1515QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const
1516{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) > 0; }
1517QT_ASCII_CAST_WARN bool QString::operator<=(const QByteArray &s) const
1518{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) <= 0; }
1519QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const
1520{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; }
1521
1522bool QByteArray::operator==(const QString &s) const
1523{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) == 0; }
1524bool QByteArray::operator!=(const QString &s) const
1525{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) != 0; }
1526bool QByteArray::operator<(const QString &s) const
1527{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; }
1528bool QByteArray::operator>(const QString &s) const
1529{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) < 0; }
1530bool QByteArray::operator<=(const QString &s) const
1531{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) >= 0; }
1532bool QByteArray::operator>=(const QString &s) const
1533{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) <= 0; }
1534#endif // QT_CORE_REMOVED_SINCE(6, 8)
1535#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1536
1537#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
1538// QString + QString
1539inline QString operator+(const QString &s1, const QString &s2)
1540{ QString t(s1); t += s2; return t; }
1541inline QString operator+(QString &&lhs, const QString &rhs)
1542{ return std::move(lhs += rhs); }
1543inline QString operator+(const QString &s1, QChar s2)
1544{ QString t(s1); t += s2; return t; }
1545inline QString operator+(QString &&lhs, QChar rhs)
1546{ return std::move(lhs += rhs); }
1547inline QString operator+(QChar s1, const QString &s2)
1548{ QString t(s1); t += s2; return t; }
1549inline QString operator+(const QString &lhs, QStringView rhs)
1550{
1551 QString ret{lhs.size() + rhs.size(), Qt::Uninitialized};
1552 return ret.assign(lhs).append(rhs);
1553}
1554inline QString operator+(QStringView lhs, const QString &rhs)
1555{
1556 QString ret{lhs.size() + rhs.size(), Qt::Uninitialized};
1557 return ret.assign(lhs).append(rhs);
1558}
1559
1560# if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1561QT_ASCII_CAST_WARN inline QString operator+(const QString &s1, const char *s2)
1562{ QString t(s1); t += QUtf8StringView(s2); return t; }
1563QT_ASCII_CAST_WARN inline QString operator+(QString &&lhs, const char *rhs)
1564{ QT_IGNORE_DEPRECATIONS(return std::move(lhs += rhs);) }
1565QT_ASCII_CAST_WARN inline QString operator+(const char *s1, const QString &s2)
1566{ QString t = QString::fromUtf8(s1); t += s2; return t; }
1567QT_ASCII_CAST_WARN inline QString operator+(const QByteArray &ba, const QString &s)
1568{ QString t = QString::fromUtf8(ba); t += s; return t; }
1569QT_ASCII_CAST_WARN inline QString operator+(const QString &s, const QByteArray &ba)
1570{ QString t(s); t += QUtf8StringView(ba); return t; }
1571QT_ASCII_CAST_WARN inline QString operator+(QString &&lhs, const QByteArray &rhs)
1572{ QT_IGNORE_DEPRECATIONS(return std::move(lhs += rhs);) }
1573# endif // QT_NO_CAST_FROM_ASCII
1574#endif // QT_USE_QSTRINGBUILDER
1575
1576QString QString::fromStdString(const std::string &s)
1577{ return fromUtf8(s.data(), qsizetype(s.size())); }
1578
1579std::wstring QString::toStdWString() const
1580{
1581 std::wstring str;
1582 str.resize(size());
1583 str.resize(toWCharArray(str.data()));
1584 return str;
1585}
1586
1587QString QString::fromStdWString(const std::wstring &s)
1588{ return fromWCharArray(s.data(), qsizetype(s.size())); }
1589
1590QString QString::fromStdU16String(const std::u16string &s)
1591{ return fromUtf16(s.data(), qsizetype(s.size())); }
1592
1593std::u16string QString::toStdU16String() const
1594{ return std::u16string(reinterpret_cast<const char16_t*>(data()), size()); }
1595
1596QString QString::fromStdU32String(const std::u32string &s)
1597{ return fromUcs4(s.data(), qsizetype(s.size())); }
1598
1599std::u32string QString::toStdU32String() const
1600{
1601 std::u32string u32str(size(), char32_t(0));
1602 const qsizetype len = toUcs4_helper(reinterpret_cast<const char16_t *>(data()),
1603 size(), u32str.data());
1604 u32str.resize(len);
1605 return u32str;
1606}
1607
1608QString::operator std::u16string_view() const noexcept
1609{
1610 return std::u16string_view(d.data(), size_t(d.size));
1611}
1612
1613#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
1614Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QString &);
1615Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QString &);
1616#endif
1617
1619Q_DECLARE_OPERATORS_FOR_FLAGS(QString::SectionFlags)
1620
1621int QString::compare(QStringView s, Qt::CaseSensitivity cs) const noexcept
1622{ return -s.compare(*this, cs); }
1623
1624int QString::localeAwareCompare(QStringView s) const
1625{ return localeAwareCompare_helper(constData(), size(), s.constData(), s.size()); }
1626int QString::localeAwareCompare(QStringView s1, QStringView s2)
1627{ return localeAwareCompare_helper(s1.constData(), s1.size(), s2.constData(), s2.size()); }
1628int QStringView::localeAwareCompare(QStringView other) const
1629{ return QString::localeAwareCompare(*this, other); }
1630
1631#if QT_CORE_INLINE_IMPL_SINCE(6, 5)
1632qint64 QString::toLongLong(bool *ok, int base) const
1633{
1634 return toIntegral_helper<qlonglong>(*this, ok, base);
1635}
1636
1637quint64 QString::toULongLong(bool *ok, int base) const
1638{
1639 return toIntegral_helper<qulonglong>(*this, ok, base);
1640}
1641#endif
1642#if QT_CORE_INLINE_IMPL_SINCE(6, 8)
1643qsizetype QString::indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const
1644{
1645 return qToStringViewIgnoringNull(*this).indexOf(ch, from, cs);
1646}
1647qsizetype QString::lastIndexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const
1648{
1649 return qToStringViewIgnoringNull(*this).lastIndexOf(ch, from, cs);
1650}
1651#endif
1652#if QT_CORE_INLINE_IMPL_SINCE(6, 10)
1653QString QString::fromRawData(const QChar *unicode, qsizetype size)
1654{
1655 return fromRawData(reinterpret_cast<const char16_t *>(unicode), size);
1656}
1657#endif
1658
1659namespace QtPrivate {
1660// used by qPrintable() and qUtf8Printable() macros
1661inline const QString &asString(const QString &s) { return s; }
1662inline QString &&asString(QString &&s) { return std::move(s); }
1663}
1664
1665#ifndef qPrintable
1666# define qPrintable(string) QtPrivate::asString(string).toLocal8Bit().constData()
1667#endif
1668
1669#ifndef qUtf8Printable
1670# define qUtf8Printable(string) QtPrivate::asString(string).toUtf8().constData()
1671#endif
1672
1673/*
1674 Wrap QString::utf16() with enough casts to allow passing it
1675 to QString::asprintf("%ls") without warnings.
1676*/
1677#ifndef qUtf16Printable
1678# define qUtf16Printable(string)
1679 static_cast<const wchar_t*>(static_cast<const void*>(QtPrivate::asString(string).utf16()))
1680#endif
1681
1682//
1683// QStringView::arg() implementation
1684//
1685
1686namespace QtPrivate {
1687
1688struct ArgBase {
1689 enum Tag : uchar { L1, Any, U16 } tag;
1690};
1691
1694 QStringViewArg() = default;
1695 constexpr explicit QStringViewArg(QStringView v) noexcept : ArgBase{U16}, string{v} {}
1696};
1697
1700 QLatin1StringArg() = default;
1701 constexpr explicit QLatin1StringArg(QLatin1StringView v) noexcept : ArgBase{L1}, string{v} {}
1702};
1703
1706 QAnyStringArg() = default;
1707 constexpr explicit QAnyStringArg(QAnyStringView v) noexcept : ArgBase{Any}, string{v} {}
1708};
1709
1710#if QT_CORE_REMOVED_SINCE(6, 9)
1713#endif
1714[[nodiscard]] Q_CORE_EXPORT QString argToQString(QAnyStringView pattern, size_t n, const ArgBase **args);
1715
1716template <typename...Args>
1717[[nodiscard]] Q_ALWAYS_INLINE QString argToQStringDispatch(QAnyStringView pattern, const Args &...args)
1718{
1719 const ArgBase *argBases[] = {&args..., /* avoid zero-sized array */ nullptr};
1720 return QtPrivate::argToQString(pattern, sizeof...(Args), argBases);
1721}
1722
1723constexpr inline QAnyStringArg qStringLikeToArg(QAnyStringView s) noexcept { return QAnyStringArg{s}; }
1724
1725} // namespace QtPrivate
1726
1727template <typename...Args>
1729QString QStringView::arg(Args &&...args) const
1730{
1731 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1732}
1733
1734template <typename...Args>
1736QString QLatin1StringView::arg(Args &&...args) const
1737{
1738 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1739}
1740
1741template <bool HasChar8T>
1742template <typename...Args>
1743QString QBasicUtf8StringView<HasChar8T>::arg(Args &&...args) const
1744{
1745 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1746}
1747
1748template <typename...Args>
1749QString QAnyStringView::arg(Args &&...args) const
1750{
1751 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
1752}
1753
1754template <typename T>
1755qsizetype erase(QString &s, const T &t)
1756{
1757 return s.removeIf_helper([&t](const auto &e) { return t == e; });
1758}
1759
1760template <typename Predicate>
1761qsizetype erase_if(QString &s, Predicate pred)
1762{
1763 return s.removeIf_helper(pred);
1764}
1765
1766namespace Qt {
1767inline namespace Literals {
1768inline namespace StringLiterals {
1769inline QString operator""_s(const char16_t *str, size_t size) noexcept
1770{
1771 return QString(QStringPrivate(nullptr, const_cast<char16_t *>(str), qsizetype(size)));
1772}
1773
1774} // StringLiterals
1775} // Literals
1776} // Qt
1777
1778inline namespace QtLiterals {
1779#if QT_DEPRECATED_SINCE(6, 8)
1780
1781QT_DEPRECATED_VERSION_X_6_8("Use _s from Qt::StringLiterals namespace instead.")
1782inline QString operator""_qs(const char16_t *str, size_t size) noexcept
1783{
1784 return Qt::StringLiterals::operator""_s(str, size);
1785}
1786
1787#endif // QT_DEPRECATED_SINCE(6, 8)
1788} // QtLiterals
1789
1790QT_END_NAMESPACE
1791
1792#include <QtCore/qstringbuilder.h>
1793#include <QtCore/qstringconverter.h>
1794
1795#ifdef Q_L1S_VIEW_IS_PRIMARY
1796# undef Q_L1S_VIEW_IS_PRIMARY
1797#endif
1798
1799#endif // QSTRING_H
\inmodule QtCore\reentrant
Definition qdatastream.h:49
QString && asString(QString &&s)
Definition qstring.h:1662
constexpr QAnyStringArg qStringLikeToArg(QAnyStringView s) noexcept
Definition qstring.h:1723
const QString & asString(const QString &s)
Definition qstring.h:1661
constexpr bool isLatin1(QLatin1StringView s) noexcept
Definition qstring.h:78
QString operator""_s(const char16_t *str, size_t size) noexcept
Definition qstring.h:1769
Definition qcompare.h:76
#define __has_cpp_attribute(x)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n)
\inmodule QtCore \title Global Qt Declarations
Definition qglobal.cpp:99
QString operator+(const QString &s1, QChar s2)
Definition qstring.h:1543
QString operator+(QString &&lhs, const QString &rhs)
Definition qstring.h:1541
qsizetype erase_if(QString &s, Predicate pred)
Definition qstring.h:1761
QString operator+(QString &&lhs, QChar rhs)
Definition qstring.h:1545
QString operator+(QChar s1, const QString &s2)
Definition qstring.h:1547
QString operator+(const QString &s1, const QString &s2)
Definition qstring.h:1539
qsizetype erase(QString &s, const T &t)
Definition qstring.h:1755
QList< QList< qInternalCallback > > callbacks
Definition qglobal.cpp:128
constexpr QAnyStringArg(QAnyStringView v) noexcept
Definition qstring.h:1707
QAnyStringView string
Definition qstring.h:1705
QLatin1StringView string
Definition qstring.h:1699
constexpr QLatin1StringArg(QLatin1StringView v) noexcept
Definition qstring.h:1701
constexpr QStringViewArg(QStringView v) noexcept
Definition qstring.h:1695