1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Copyright (C) 2019 Mail.ru Group.
6** Contact: https://www.qt.io/licensing/
7**
8** This file is part of the QtCore module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial License Usage
12** Licensees holding valid commercial Qt licenses may use this file in
13** accordance with the commercial license agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and The Qt Company. For licensing terms
16** and conditions see https://www.qt.io/terms-conditions. For further
17** information use the contact form at https://www.qt.io/contact-us.
18**
19** GNU Lesser General Public License Usage
20** Alternatively, this file may be used under the terms of the GNU Lesser
21** General Public License version 3 as published by the Free Software
22** Foundation and appearing in the file LICENSE.LGPL3 included in the
23** packaging of this file. Please review the following information to
24** ensure the GNU Lesser General Public License version 3 requirements
25** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26**
27** GNU General Public License Usage
28** Alternatively, this file may be used under the terms of the GNU
29** General Public License version 2.0 or (at your option) the GNU General
30** Public license version 3 or any later version approved by the KDE Free
31** Qt Foundation. The licenses are as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33** included in the packaging of this file. Please review the following
34** information to ensure the GNU General Public License requirements will
35** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36** https://www.gnu.org/licenses/gpl-3.0.html.
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QSTRING_H
43#define QSTRING_H
44
45#if defined(QT_NO_CAST_FROM_ASCII) && defined(QT_RESTRICTED_CAST_FROM_ASCII)
46#error QT_NO_CAST_FROM_ASCII and QT_RESTRICTED_CAST_FROM_ASCII must not be defined at the same time
47#endif
48
49#include <QtCore/qchar.h>
50#include <QtCore/qbytearray.h>
51#include <QtCore/qrefcount.h>
52#include <QtCore/qnamespace.h>
53#include <QtCore/qstringliteral.h>
54#include <QtCore/qstringalgorithms.h>
55#include <QtCore/qstringview.h>
56
57#include <string>
58#include <iterator>
59
60#include <stdarg.h>
61
62#ifdef truncate
63#error qstring.h must be included before any header file that defines truncate
64#endif
65
66#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
67Q_FORWARD_DECLARE_CF_TYPE(CFString);
68Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
69#endif
70
71QT_BEGIN_NAMESPACE
72
73class QCharRef;
74class QRegExp;
75class QRegularExpression;
76class QRegularExpressionMatch;
77class QString;
78class QStringList;
79class QTextCodec;
80class QStringRef;
81template <typename T> class QVector;
82
83namespace QtPrivate {
84template <bool...B> class BoolList;
85}
86
87class QLatin1String
88{
89public:
90 Q_DECL_CONSTEXPR inline QLatin1String() noexcept : m_size(0), m_data(nullptr) {}
91 Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) noexcept : m_size(s ? int(strlen(s)) : 0), m_data(s) {}
92 Q_DECL_CONSTEXPR explicit QLatin1String(const char *f, const char *l)
93 : QLatin1String(f, int(l - f)) {}
94 Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) noexcept : m_size(sz), m_data(s) {}
95 inline explicit QLatin1String(const QByteArray &s) noexcept : m_size(int(qstrnlen(s.constData(), s.size()))), m_data(s.constData()) {}
96
97 Q_DECL_CONSTEXPR const char *latin1() const noexcept { return m_data; }
98 Q_DECL_CONSTEXPR int size() const noexcept { return m_size; }
99 Q_DECL_CONSTEXPR const char *data() const noexcept { return m_data; }
100
101 Q_DECL_CONSTEXPR bool isNull() const noexcept { return !data(); }
102 Q_DECL_CONSTEXPR bool isEmpty() const noexcept { return !size(); }
103
104 template <typename...Args>
105 Q_REQUIRED_RESULT inline QString arg(Args &&...args) const;
106
107 Q_DECL_CONSTEXPR QLatin1Char at(int i) const
108 { return Q_ASSERT(i >= 0), Q_ASSERT(i < size()), QLatin1Char(m_data[i]); }
109 Q_DECL_CONSTEXPR QLatin1Char operator[](int i) const { return at(i); }
110
111 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QLatin1Char front() const { return at(0); }
112 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QLatin1Char back() const { return at(size() - 1); }
113
114 Q_REQUIRED_RESULT int compare(QStringView other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
115 { return QtPrivate::compareStrings(*this, other, cs); }
116 Q_REQUIRED_RESULT int compare(QLatin1String other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
117 { return QtPrivate::compareStrings(*this, other, cs); }
118 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR int compare(QChar c) const noexcept
119 { return isEmpty() || front() == c ? size() - 1 : uchar(m_data[0]) - c.unicode() ; }
120 Q_REQUIRED_RESULT int compare(QChar c, Qt::CaseSensitivity cs) const noexcept
121 { return QtPrivate::compareStrings(*this, QStringView(&c, 1), cs); }
122
123 Q_REQUIRED_RESULT bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
124 { return QtPrivate::startsWith(*this, s, cs); }
125 Q_REQUIRED_RESULT bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
126 { return QtPrivate::startsWith(*this, s, cs); }
127 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR bool startsWith(QChar c) const noexcept
128 { return !isEmpty() && front() == c; }
129 Q_REQUIRED_RESULT inline bool startsWith(QChar c, Qt::CaseSensitivity cs) const noexcept
130 { return QtPrivate::startsWith(*this, QStringView(&c, 1), cs); }
131
132 Q_REQUIRED_RESULT bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
133 { return QtPrivate::endsWith(*this, s, cs); }
134 Q_REQUIRED_RESULT bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
135 { return QtPrivate::endsWith(*this, s, cs); }
136 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR bool endsWith(QChar c) const noexcept
137 { return !isEmpty() && back() == c; }
138 Q_REQUIRED_RESULT inline bool endsWith(QChar c, Qt::CaseSensitivity cs) const noexcept
139 { return QtPrivate::endsWith(*this, QStringView(&c, 1), cs); }
140
141 Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
142 { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
143 Q_REQUIRED_RESULT int indexOf(QLatin1String s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
144 { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
145 Q_REQUIRED_RESULT inline int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
146 { return int(QtPrivate::findString(*this, from, QStringView(&c, 1), cs)); } // ### Qt6: qsizetype
147
148 Q_REQUIRED_RESULT bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
149 { return indexOf(s, 0, cs) != -1; }
150 Q_REQUIRED_RESULT bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
151 { return indexOf(s, 0, cs) != -1; }
152 Q_REQUIRED_RESULT inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
153 { return indexOf(QStringView(&c, 1), 0, cs) != -1; }
154
155 Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
156 { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
157 Q_REQUIRED_RESULT int lastIndexOf(QLatin1String s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
158 { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
159 Q_REQUIRED_RESULT inline int lastIndexOf(QChar c, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
160 { return int(QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs)); } // ### Qt6: qsizetype
161
162 using value_type = const char;
163 using reference = value_type&;
164 using const_reference = reference;
165 using iterator = value_type*;
166 using const_iterator = iterator;
167 using difference_type = int; // violates Container concept requirements
168 using size_type = int; // violates Container concept requirements
169
170 Q_DECL_CONSTEXPR const_iterator begin() const noexcept { return data(); }
171 Q_DECL_CONSTEXPR const_iterator cbegin() const noexcept { return data(); }
172 Q_DECL_CONSTEXPR const_iterator end() const noexcept { return data() + size(); }
173 Q_DECL_CONSTEXPR const_iterator cend() const noexcept { return data() + size(); }
174
175 using reverse_iterator = std::reverse_iterator<iterator>;
176 using const_reverse_iterator = reverse_iterator;
177
178 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
179 const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
180 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
181 const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
182
183 Q_DECL_CONSTEXPR QLatin1String mid(int pos) const
184 { return Q_ASSERT(pos >= 0), Q_ASSERT(pos <= size()), QLatin1String(m_data + pos, m_size - pos); }
185 Q_DECL_CONSTEXPR QLatin1String mid(int pos, int n) const
186 { return Q_ASSERT(pos >= 0), Q_ASSERT(n >= 0), Q_ASSERT(pos + n <= size()), QLatin1String(m_data + pos, n); }
187 Q_DECL_CONSTEXPR QLatin1String left(int n) const
188 { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QLatin1String(m_data, n); }
189 Q_DECL_CONSTEXPR QLatin1String right(int n) const
190 { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QLatin1String(m_data + m_size - n, n); }
191 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QLatin1String chopped(int n) const
192 { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QLatin1String(m_data, m_size - n); }
193
194 Q_DECL_RELAXED_CONSTEXPR void chop(int n)
195 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size -= n; }
196 Q_DECL_RELAXED_CONSTEXPR void truncate(int n)
197 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size = n; }
198
199 Q_REQUIRED_RESULT QLatin1String trimmed() const noexcept { return QtPrivate::trimmed(*this); }
200
201 inline bool operator==(const QString &s) const noexcept;
202 inline bool operator!=(const QString &s) const noexcept;
203 inline bool operator>(const QString &s) const noexcept;
204 inline bool operator<(const QString &s) const noexcept;
205 inline bool operator>=(const QString &s) const noexcept;
206 inline bool operator<=(const QString &s) const noexcept;
207
208#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
209 inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
210 inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
211 inline QT_ASCII_CAST_WARN bool operator<(const char *s) const;
212 inline QT_ASCII_CAST_WARN bool operator>(const char *s) const;
213 inline QT_ASCII_CAST_WARN bool operator<=(const char *s) const;
214 inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const;
215
216 inline QT_ASCII_CAST_WARN bool operator==(const QByteArray &s) const;
217 inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &s) const;
218 inline QT_ASCII_CAST_WARN bool operator<(const QByteArray &s) const;
219 inline QT_ASCII_CAST_WARN bool operator>(const QByteArray &s) const;
220 inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &s) const;
221 inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &s) const;
222#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
223
224private:
225 int m_size;
226 const char *m_data;
227};
228Q_DECLARE_TYPEINFO(QLatin1String, Q_MOVABLE_TYPE);
229
230// Qt 4.x compatibility
231#if QT_DEPRECATED_SINCE(5, 14)
232QT_DEPRECATED_X("Use QLatin1String")
233typedef QLatin1String QLatin1Literal;
234#endif
235
236//
237// QLatin1String inline implementations
238//
239Q_DECL_CONSTEXPR bool QtPrivate::isLatin1(QLatin1String) noexcept
240{ return true; }
241
242//
243// QStringView members that require QLatin1String:
244//
245int QStringView::compare(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
246{ return QtPrivate::compareStrings(*this, s, cs); }
247bool QStringView::startsWith(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
248{ return QtPrivate::startsWith(*this, s, cs); }
249bool QStringView::endsWith(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
250{ return QtPrivate::endsWith(*this, s, cs); }
251qsizetype QStringView::indexOf(QLatin1String s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
252{ return QtPrivate::findString(*this, from, s, cs); }
253bool QStringView::contains(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
254{ return indexOf(s, 0, cs) != qsizetype(-1); }
255qsizetype QStringView::lastIndexOf(QLatin1String s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
256{ return QtPrivate::lastIndexOf(*this, from, s, cs); }
257
258class Q_CORE_EXPORT QString
259{
260public:
261 typedef QStringData Data;
262
263 inline QString() noexcept;
264 explicit QString(const QChar *unicode, int size = -1);
265 QString(QChar c);
266 QString(int size, QChar c);
267 inline QString(QLatin1String latin1);
268 inline QString(const QString &) noexcept;
269 inline ~QString();
270 QString &operator=(QChar c);
271 QString &operator=(const QString &) noexcept;
272 QString &operator=(QLatin1String latin1);
273 inline QString(QString && other) noexcept : d(other.d) { other.d = Data::sharedNull(); }
274 inline QString &operator=(QString &&other) noexcept
275 { qSwap(d, other.d); return *this; }
276 inline void swap(QString &other) noexcept { qSwap(d, other.d); }
277 inline int size() const { return d->size; }
278 inline int count() const { return d->size; }
279 inline int length() const;
280 inline bool isEmpty() const;
281 void resize(int size);
282 void resize(int size, QChar fillChar);
283
284 QString &fill(QChar c, int size = -1);
285 void truncate(int pos);
286 void chop(int n);
287
288 int capacity() const;
289 inline void reserve(int size);
290 inline void squeeze();
291
292 inline const QChar *unicode() const;
293 inline QChar *data();
294 inline const QChar *data() const;
295 inline const QChar *constData() const;
296
297 inline void detach();
298 inline bool isDetached() const;
299 inline bool isSharedWith(const QString &other) const { return d == other.d; }
300 void clear();
301
302 inline const QChar at(int i) const;
303 const QChar operator[](int i) const;
304 Q_REQUIRED_RESULT QCharRef operator[](int i);
305 const QChar operator[](uint i) const;
306 Q_REQUIRED_RESULT QCharRef operator[](uint i);
307
308 Q_REQUIRED_RESULT inline QChar front() const { return at(0); }
309 Q_REQUIRED_RESULT inline QCharRef front();
310 Q_REQUIRED_RESULT inline QChar back() const { return at(size() - 1); }
311 Q_REQUIRED_RESULT inline QCharRef back();
312
313 Q_REQUIRED_RESULT QString arg(qlonglong a, int fieldwidth=0, int base=10,
314 QChar fillChar = QLatin1Char(' ')) const;
315 Q_REQUIRED_RESULT QString arg(qulonglong a, int fieldwidth=0, int base=10,
316 QChar fillChar = QLatin1Char(' ')) const;
317 Q_REQUIRED_RESULT QString arg(long a, int fieldwidth=0, int base=10,
318 QChar fillChar = QLatin1Char(' ')) const;
319 Q_REQUIRED_RESULT QString arg(ulong a, int fieldwidth=0, int base=10,
320 QChar fillChar = QLatin1Char(' ')) const;
321 Q_REQUIRED_RESULT QString arg(int a, int fieldWidth = 0, int base = 10,
322 QChar fillChar = QLatin1Char(' ')) const;
323 Q_REQUIRED_RESULT QString arg(uint a, int fieldWidth = 0, int base = 10,
324 QChar fillChar = QLatin1Char(' ')) const;
325 Q_REQUIRED_RESULT QString arg(short a, int fieldWidth = 0, int base = 10,
326 QChar fillChar = QLatin1Char(' ')) const;
327 Q_REQUIRED_RESULT QString arg(ushort a, int fieldWidth = 0, int base = 10,
328 QChar fillChar = QLatin1Char(' ')) const;
329 Q_REQUIRED_RESULT QString arg(double a, int fieldWidth = 0, char fmt = 'g', int prec = -1,
330 QChar fillChar = QLatin1Char(' ')) const;
331 Q_REQUIRED_RESULT QString arg(char a, int fieldWidth = 0,
332 QChar fillChar = QLatin1Char(' ')) const;
333 Q_REQUIRED_RESULT QString arg(QChar a, int fieldWidth = 0,
334 QChar fillChar = QLatin1Char(' ')) const;
335#if QT_STRINGVIEW_LEVEL < 2
336 Q_REQUIRED_RESULT QString arg(const QString &a, int fieldWidth = 0,
337 QChar fillChar = QLatin1Char(' ')) const;
338#endif
339 Q_REQUIRED_RESULT QString arg(QStringView a, int fieldWidth = 0,
340 QChar fillChar = QLatin1Char(' ')) const;
341 Q_REQUIRED_RESULT QString arg(QLatin1String a, int fieldWidth = 0,
342 QChar fillChar = QLatin1Char(' ')) const;
343#if QT_STRINGVIEW_LEVEL < 2
344 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2) const;
345 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3) const;
346 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3,
347 const QString &a4) const;
348 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3,
349 const QString &a4, const QString &a5) const;
350 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3,
351 const QString &a4, const QString &a5, const QString &a6) const;
352 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3,
353 const QString &a4, const QString &a5, const QString &a6,
354 const QString &a7) const;
355 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3,
356 const QString &a4, const QString &a5, const QString &a6,
357 const QString &a7, const QString &a8) const;
358 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3,
359 const QString &a4, const QString &a5, const QString &a6,
360 const QString &a7, const QString &a8, const QString &a9) const;
361#endif
362private:
363 template <typename T>
364 struct is_convertible_to_view_or_qstring_helper
365 : std::integral_constant<bool,
366 std::is_convertible<T, QString>::value ||
367 std::is_convertible<T, QStringView>::value ||
368 std::is_convertible<T, QLatin1String>::value> {};
369 template <typename T>
370 struct is_convertible_to_view_or_qstring
371 : is_convertible_to_view_or_qstring_helper<typename std::decay<T>::type> {};
372public:
373 template <typename...Args>
374 Q_REQUIRED_RESULT
375#ifdef Q_CLANG_QDOC
376 QString
377#else
378 typename std::enable_if<
379 sizeof...(Args) >= 2 && std::is_same<
380 QtPrivate::BoolList<is_convertible_to_view_or_qstring<Args>::value..., true>,
381 QtPrivate::BoolList<true, is_convertible_to_view_or_qstring<Args>::value...>
382 >::value,
383 QString
384 >::type
385#endif
386 arg(Args &&...args) const
387 { return qToStringViewIgnoringNull(*this).arg(std::forward<Args>(args)...); }
388
389#if QT_DEPRECATED_SINCE(5, 14)
390 QT_DEPRECATED_X("Use vasprintf(), arg() or QTextStream instead")
391 QString &vsprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(2, 0);
392 QT_DEPRECATED_X("Use asprintf(), arg() or QTextStream instead")
393 QString &sprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
394#endif
395 static QString vasprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(1, 0);
396 static QString asprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
397
398 int indexOf(QChar c, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
399 int indexOf(QLatin1String s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
400#if QT_STRINGVIEW_LEVEL < 2
401 int indexOf(const QString &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
402 int indexOf(const QStringRef &s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
403#endif
404 Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
405 { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
406 int lastIndexOf(QChar c, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
407 int lastIndexOf(QLatin1String s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
408#if QT_STRINGVIEW_LEVEL < 2
409 int lastIndexOf(const QString &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
410 int lastIndexOf(const QStringRef &s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
411#endif
412
413 Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
414 { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
415
416 inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
417#if QT_STRINGVIEW_LEVEL < 2
418 inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
419 inline bool contains(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
420#endif
421 inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
422 inline bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
423 int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
424 int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
425 int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
426
427#ifndef QT_NO_REGEXP
428 int indexOf(const QRegExp &, int from = 0) const;
429 int lastIndexOf(const QRegExp &, int from = -1) const;
430 inline bool contains(const QRegExp &rx) const { return indexOf(rx) != -1; }
431 int count(const QRegExp &) const;
432
433 int indexOf(QRegExp &, int from = 0) const;
434 int lastIndexOf(QRegExp &, int from = -1) const;
435 inline bool contains(QRegExp &rx) const { return indexOf(rx) != -1; }
436#endif
437
438#if QT_CONFIG(regularexpression)
439 int indexOf(const QRegularExpression &re, int from = 0) const;
440 int indexOf(const QRegularExpression &re, int from, QRegularExpressionMatch *rmatch) const; // ### Qt 6: merge overloads
441 int lastIndexOf(const QRegularExpression &re, int from = -1) const;
442 int lastIndexOf(const QRegularExpression &re, int from, QRegularExpressionMatch *rmatch) const; // ### Qt 6: merge overloads
443 bool contains(const QRegularExpression &re) const;
444 bool contains(const QRegularExpression &re, QRegularExpressionMatch *rmatch) const; // ### Qt 6: merge overloads
445 int count(const QRegularExpression &re) const;
446#endif
447
448 enum SectionFlag {
449 SectionDefault = 0x00,
450 SectionSkipEmpty = 0x01,
451 SectionIncludeLeadingSep = 0x02,
452 SectionIncludeTrailingSep = 0x04,
453 SectionCaseInsensitiveSeps = 0x08
454 };
455 Q_DECLARE_FLAGS(SectionFlags, SectionFlag)
456
457 QString section(QChar sep, int start, int end = -1, SectionFlags flags = SectionDefault) const;
458 QString section(const QString &in_sep, int start, int end = -1, SectionFlags flags = SectionDefault) const;
459#ifndef QT_NO_REGEXP
460 QString section(const QRegExp &reg, int start, int end = -1, SectionFlags flags = SectionDefault) const;
461#endif
462#if QT_CONFIG(regularexpression)
463 QString section(const QRegularExpression &re, int start, int end = -1, SectionFlags flags = SectionDefault) const;
464#endif
465 Q_REQUIRED_RESULT QString left(int n) const;
466 Q_REQUIRED_RESULT QString right(int n) const;
467 Q_REQUIRED_RESULT QString mid(int position, int n = -1) const;
468 Q_REQUIRED_RESULT QString chopped(int n) const
469 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return left(size() - n); }
470
471
472 Q_REQUIRED_RESULT QStringRef leftRef(int n) const;
473 Q_REQUIRED_RESULT QStringRef rightRef(int n) const;
474 Q_REQUIRED_RESULT QStringRef midRef(int position, int n = -1) const;
475
476#if QT_STRINGVIEW_LEVEL < 2
477 bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
478 bool startsWith(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
479#endif
480 Q_REQUIRED_RESULT bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
481 { return QtPrivate::startsWith(*this, s, cs); }
482 bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
483 bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
484
485#if QT_STRINGVIEW_LEVEL < 2
486 bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
487 bool endsWith(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
488#endif
489 Q_REQUIRED_RESULT bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
490 { return QtPrivate::endsWith(*this, s, cs); }
491 bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
492 bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
493
494 bool isUpper() const;
495 bool isLower() const;
496
497 Q_REQUIRED_RESULT QString leftJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const;
498 Q_REQUIRED_RESULT QString rightJustified(int width, QChar fill = QLatin1Char(' '), bool trunc = false) const;
499
500#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC)
501# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !__has_cpp_attribute(nodiscard)
502 // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
503# pragma push_macro("Q_REQUIRED_RESULT")
504# undef Q_REQUIRED_RESULT
505# define Q_REQUIRED_RESULT
506# define Q_REQUIRED_RESULT_pushed
507# endif
508 Q_REQUIRED_RESULT QString toLower() const &
509 { return toLower_helper(*this); }
510 Q_REQUIRED_RESULT QString toLower() &&
511 { return toLower_helper(*this); }
512 Q_REQUIRED_RESULT QString toUpper() const &
513 { return toUpper_helper(*this); }
514 Q_REQUIRED_RESULT QString toUpper() &&
515 { return toUpper_helper(*this); }
516 Q_REQUIRED_RESULT QString toCaseFolded() const &
517 { return toCaseFolded_helper(*this); }
518 Q_REQUIRED_RESULT QString toCaseFolded() &&
519 { return toCaseFolded_helper(*this); }
520 Q_REQUIRED_RESULT QString trimmed() const &
521 { return trimmed_helper(*this); }
522 Q_REQUIRED_RESULT QString trimmed() &&
523 { return trimmed_helper(*this); }
524 Q_REQUIRED_RESULT QString simplified() const &
525 { return simplified_helper(*this); }
526 Q_REQUIRED_RESULT QString simplified() &&
527 { return simplified_helper(*this); }
528# ifdef Q_REQUIRED_RESULT_pushed
529# pragma pop_macro("Q_REQUIRED_RESULT")
530# endif
531#else
532 Q_REQUIRED_RESULT QString toLower() const;
533 Q_REQUIRED_RESULT QString toUpper() const;
534 Q_REQUIRED_RESULT QString toCaseFolded() const;
535 Q_REQUIRED_RESULT QString trimmed() const;
536 Q_REQUIRED_RESULT QString simplified() const;
537#endif
538 Q_REQUIRED_RESULT QString toHtmlEscaped() const;
539
540 QString &insert(int i, QChar c);
541 QString &insert(int i, const QChar *uc, int len);
542 inline QString &insert(int i, const QString &s) { return insert(i, s.constData(), s.length()); }
543 inline QString &insert(int i, const QStringRef &s);
544 inline QString &insert(int i, QStringView s)
545 { return insert(i, s.data(), s.length()); }
546 QString &insert(int i, QLatin1String s);
547 QString &append(QChar c);
548 QString &append(const QChar *uc, int len);
549 QString &append(const QString &s);
550 QString &append(const QStringRef &s);
551 QString &append(QLatin1String s);
552 inline QString &append(QStringView s) { return append(s.data(), s.length()); }
553 inline QString &prepend(QChar c) { return insert(0, c); }
554 inline QString &prepend(const QChar *uc, int len) { return insert(0, uc, len); }
555 inline QString &prepend(const QString &s) { return insert(0, s); }
556 inline QString &prepend(const QStringRef &s) { return insert(0, s); }
557 inline QString &prepend(QLatin1String s) { return insert(0, s); }
558 inline QString &prepend(QStringView s) { return insert(0, s); }
559
560 inline QString &operator+=(QChar c) {
561 if (d->ref.isShared() || uint(d->size) + 2u > d->alloc)
562 reallocData(uint(d->size) + 2u, true);
563 d->data()[d->size++] = c.unicode();
564 d->data()[d->size] = '\0';
565 return *this;
566 }
567
568 inline QString &operator+=(QChar::SpecialCharacter c) { return append(QChar(c)); }
569 inline QString &operator+=(const QString &s) { return append(s); }
570 inline QString &operator+=(const QStringRef &s) { return append(s); }
571 inline QString &operator+=(QLatin1String s) { return append(s); }
572 inline QString &operator+=(QStringView s) { return append(s); }
573
574 QString &remove(int i, int len);
575 QString &remove(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive);
576 QString &remove(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
577 QString &remove(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive);
578 QString &replace(int i, int len, QChar after);
579 QString &replace(int i, int len, const QChar *s, int slen);
580 QString &replace(int i, int len, const QString &after);
581 QString &replace(QChar before, QChar after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
582 QString &replace(const QChar *before, int blen, const QChar *after, int alen, Qt::CaseSensitivity cs = Qt::CaseSensitive);
583 QString &replace(QLatin1String before, QLatin1String after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
584 QString &replace(QLatin1String before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
585 QString &replace(const QString &before, QLatin1String after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
586 QString &replace(const QString &before, const QString &after,
587 Qt::CaseSensitivity cs = Qt::CaseSensitive);
588 QString &replace(QChar c, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
589 QString &replace(QChar c, QLatin1String after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
590#ifndef QT_NO_REGEXP
591 QString &replace(const QRegExp &rx, const QString &after);
592 inline QString &remove(const QRegExp &rx)
593 { return replace(rx, QString()); }
594#endif
595#if QT_CONFIG(regularexpression)
596 QString &replace(const QRegularExpression &re, const QString &after);
597 inline QString &remove(const QRegularExpression &re)
598 { return replace(re, QString()); }
599#endif
600
601#if QT_DEPRECATED_SINCE(5, 15)
602 enum SplitBehavior // ### Qt 6: replace with Qt:: version
603 {
604 KeepEmptyParts Q_DECL_ENUMERATOR_DEPRECATED,
605 SkipEmptyParts Q_DECL_ENUMERATOR_DEPRECATED
606 };
607
608 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use split(const QString &sep, Qt::SplitBehavior ...) variant instead")
609 QStringList split(const QString &sep, SplitBehavior behavior,
610 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
611 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use splitRef(const QString &sep, Qt::SplitBehavior ...) variant instead")
612 QVector<QStringRef> splitRef(const QString &sep, SplitBehavior behavior,
613 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
614 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use split(QChar sep, Qt::SplitBehavior ...) variant instead")
615 QStringList split(QChar sep, SplitBehavior behavior,
616 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
617 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use splitRef(QChar sep, Qt::SplitBehavior ...) variant instead")
618 QVector<QStringRef> splitRef(QChar sep, SplitBehavior behavior,
619 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
620#ifndef QT_NO_REGEXP
621 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use split(const QRegularExpression &, Qt::SplitBehavior) variant instead")
622 QStringList split(const QRegExp &sep, SplitBehavior behavior) const;
623 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use splitRef(const QRegularExpression &, Qt::SplitBehavior) variant instead")
624 QVector<QStringRef> splitRef(const QRegExp &sep, SplitBehavior behavior) const;
625#endif
626#if QT_CONFIG(regularexpression)
627 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use split(const QRegularExpression &, Qt::SplitBehavior) variant instead")
628 QStringList split(const QRegularExpression &sep, SplitBehavior behavior) const;
629 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use splitRef(const QRegularExpression &, Qt::SplitBehavior) variant instead")
630 QVector<QStringRef> splitRef(const QRegularExpression &sep, SplitBehavior behavior) const;
631#endif
632#endif // 5.15 deprecations
633
634public:
635 Q_REQUIRED_RESULT
636 QStringList split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
637 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
638 Q_REQUIRED_RESULT
639 QVector<QStringRef> splitRef(const QString &sep,
640 Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
641 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
642 Q_REQUIRED_RESULT
643 QStringList split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
644 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
645 Q_REQUIRED_RESULT
646 QVector<QStringRef> splitRef(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
647 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
648#ifndef QT_NO_REGEXP
649 Q_REQUIRED_RESULT
650 QStringList split(const QRegExp &sep,
651 Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
652 Q_REQUIRED_RESULT
653 QVector<QStringRef> splitRef(const QRegExp &sep,
654 Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
655#endif
656#ifndef QT_NO_REGULAREXPRESSION
657 Q_REQUIRED_RESULT
658 QStringList split(const QRegularExpression &sep,
659 Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
660 Q_REQUIRED_RESULT
661 QVector<QStringRef> splitRef(const QRegularExpression &sep,
662 Qt::SplitBehavior behavior = Qt::KeepEmptyParts) const;
663#endif
664
665
666 enum NormalizationForm {
667 NormalizationForm_D,
668 NormalizationForm_C,
669 NormalizationForm_KD,
670 NormalizationForm_KC
671 };
672 Q_REQUIRED_RESULT QString normalized(NormalizationForm mode, QChar::UnicodeVersion version = QChar::Unicode_Unassigned) const;
673
674 Q_REQUIRED_RESULT QString repeated(int times) const;
675
676 const ushort *utf16() const;
677
678#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC)
679 Q_REQUIRED_RESULT QByteArray toLatin1() const &
680 { return toLatin1_helper(*this); }
681 Q_REQUIRED_RESULT QByteArray toLatin1() &&
682 { return toLatin1_helper_inplace(*this); }
683 Q_REQUIRED_RESULT QByteArray toUtf8() const &
684 { return toUtf8_helper(*this); }
685 Q_REQUIRED_RESULT QByteArray toUtf8() &&
686 { return toUtf8_helper(*this); }
687 Q_REQUIRED_RESULT QByteArray toLocal8Bit() const &
688 { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
689 Q_REQUIRED_RESULT QByteArray toLocal8Bit() &&
690 { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
691#else
692 Q_REQUIRED_RESULT QByteArray toLatin1() const;
693 Q_REQUIRED_RESULT QByteArray toUtf8() const;
694 Q_REQUIRED_RESULT QByteArray toLocal8Bit() const;
695#endif
696 Q_REQUIRED_RESULT QVector<uint> toUcs4() const;
697
698 // note - this are all inline so we can benefit from strlen() compile time optimizations
699 static inline QString fromLatin1(const char *str, int size = -1)
700 {
701 QStringDataPtr dataPtr = { fromLatin1_helper(str, (str && size == -1) ? int(strlen(str)) : size) };
702 return QString(dataPtr);
703 }
704 static inline QString fromUtf8(const char *str, int size = -1)
705 {
706 return fromUtf8_helper(str, (str && size == -1) ? int(strlen(str)) : size);
707 }
708 static inline QString fromLocal8Bit(const char *str, int size = -1)
709 {
710 return fromLocal8Bit_helper(str, (str && size == -1) ? int(strlen(str)) : size);
711 }
712 static inline QString fromLatin1(const QByteArray &str)
713 { return str.isNull() ? QString() : fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); }
714 static inline QString fromUtf8(const QByteArray &str)
715 { return str.isNull() ? QString() : fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); }
716 static inline QString fromLocal8Bit(const QByteArray &str)
717 { return str.isNull() ? QString() : fromLocal8Bit(str.data(), qstrnlen(str.constData(), str.size())); }
718 static QString fromUtf16(const ushort *, int size = -1);
719 static QString fromUcs4(const uint *, int size = -1);
720 static QString fromRawData(const QChar *, int size);
721
722#if defined(Q_COMPILER_UNICODE_STRINGS)
723 static QString fromUtf16(const char16_t *str, int size = -1)
724 { return fromUtf16(reinterpret_cast<const ushort *>(str), size); }
725 static QString fromUcs4(const char32_t *str, int size = -1)
726 { return fromUcs4(reinterpret_cast<const uint *>(str), size); }
727#endif
728
729#if QT_DEPRECATED_SINCE(5, 0)
730 QT_DEPRECATED static inline QString fromAscii(const char *str, int size = -1)
731 { return fromLatin1(str, size); }
732 QT_DEPRECATED static inline QString fromAscii(const QByteArray &str)
733 { return fromLatin1(str); }
734 Q_REQUIRED_RESULT QByteArray toAscii() const
735 { return toLatin1(); }
736#endif
737
738 inline int toWCharArray(wchar_t *array) const;
739 Q_REQUIRED_RESULT static inline QString fromWCharArray(const wchar_t *string, int size = -1);
740
741 QString &setRawData(const QChar *unicode, int size);
742 QString &setUnicode(const QChar *unicode, int size);
743 inline QString &setUtf16(const ushort *utf16, int size);
744
745#if QT_STRINGVIEW_LEVEL < 2
746 int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
747 inline int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
748#endif
749 int compare(QLatin1String other, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
750 inline int compare(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
751 int compare(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
752 { return compare(QStringView{&ch, 1}, cs); }
753
754 static inline int compare(const QString &s1, const QString &s2,
755 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
756 { return s1.compare(s2, cs); }
757
758 static inline int compare(const QString &s1, QLatin1String s2,
759 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
760 { return s1.compare(s2, cs); }
761 static inline int compare(QLatin1String s1, const QString &s2,
762 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept
763 { return -s2.compare(s1, cs); }
764
765 static int compare(const QString &s1, const QStringRef &s2,
766 Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
767
768 int localeAwareCompare(const QString& s) const;
769 static int localeAwareCompare(const QString& s1, const QString& s2)
770 { return s1.localeAwareCompare(s2); }
771
772 int localeAwareCompare(const QStringRef &s) const;
773 static int localeAwareCompare(const QString& s1, const QStringRef& s2);
774
775 // ### Qt6: make inline except for the long long versions
776 short toShort(bool *ok=nullptr, int base=10) const;
777 ushort toUShort(bool *ok=nullptr, int base=10) const;
778 int toInt(bool *ok=nullptr, int base=10) const;
779 uint toUInt(bool *ok=nullptr, int base=10) const;
780 long toLong(bool *ok=nullptr, int base=10) const;
781 ulong toULong(bool *ok=nullptr, int base=10) const;
782 qlonglong toLongLong(bool *ok=nullptr, int base=10) const;
783 qulonglong toULongLong(bool *ok=nullptr, int base=10) const;
784 float toFloat(bool *ok=nullptr) const;
785 double toDouble(bool *ok=nullptr) const;
786
787 QString &setNum(short, int base=10);
788 QString &setNum(ushort, int base=10);
789 QString &setNum(int, int base=10);
790 QString &setNum(uint, int base=10);
791 QString &setNum(long, int base=10);
792 QString &setNum(ulong, int base=10);
793 QString &setNum(qlonglong, int base=10);
794 QString &setNum(qulonglong, int base=10);
795 QString &setNum(float, char f='g', int prec=6);
796 QString &setNum(double, char f='g', int prec=6);
797
798 static QString number(int, int base=10);
799 static QString number(uint, int base=10);
800 static QString number(long, int base=10);
801 static QString number(ulong, int base=10);
802 static QString number(qlonglong, int base=10);
803 static QString number(qulonglong, int base=10);
804 static QString number(double, char f='g', int prec=6);
805
806 friend Q_CORE_EXPORT bool operator==(const QString &s1, const QString &s2) noexcept;
807 friend Q_CORE_EXPORT bool operator<(const QString &s1, const QString &s2) noexcept;
808 friend inline bool operator>(const QString &s1, const QString &s2) noexcept { return s2 < s1; }
809 friend inline bool operator!=(const QString &s1, const QString &s2) noexcept { return !(s1 == s2); }
810 friend inline bool operator<=(const QString &s1, const QString &s2) noexcept { return !(s1 > s2); }
811 friend inline bool operator>=(const QString &s1, const QString &s2) noexcept { return !(s1 < s2); }
812
813 bool operator==(QLatin1String s) const noexcept;
814 bool operator<(QLatin1String s) const noexcept;
815 bool operator>(QLatin1String s) const noexcept;
816 inline bool operator!=(QLatin1String s) const noexcept { return !operator==(s); }
817 inline bool operator<=(QLatin1String s) const noexcept { return !operator>(s); }
818 inline bool operator>=(QLatin1String s) const noexcept { return !operator<(s); }
819
820 // ASCII compatibility
821#if defined(QT_RESTRICTED_CAST_FROM_ASCII)
822 template <int N>
823 inline QString(const char (&ch)[N])
824 : d(fromAscii_helper(ch, N - 1))
825 {}
826 template <int N>
827 QString(char (&)[N]) = delete;
828 template <int N>
829 inline QString &operator=(const char (&ch)[N])
830 { return (*this = fromUtf8(ch, N - 1)); }
831 template <int N>
832 QString &operator=(char (&)[N]) = delete;
833#endif
834#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
835 inline QT_ASCII_CAST_WARN QString(const char *ch)
836 : d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1))
837 {}
838 inline QT_ASCII_CAST_WARN QString(const QByteArray &a)
839 : d(fromAscii_helper(a.constData(), qstrnlen(a.constData(), a.size())))
840 {}
841 inline QT_ASCII_CAST_WARN QString &operator=(const char *ch)
842 { return (*this = fromUtf8(ch)); }
843 inline QT_ASCII_CAST_WARN QString &operator=(const QByteArray &a)
844 { return (*this = fromUtf8(a)); }
845 inline QT_ASCII_CAST_WARN QString &operator=(char c)
846 { return (*this = QChar::fromLatin1(c)); }
847
848 // these are needed, so it compiles with STL support enabled
849 inline QT_ASCII_CAST_WARN QString &prepend(const char *s)
850 { return prepend(QString::fromUtf8(s)); }
851 inline QT_ASCII_CAST_WARN QString &prepend(const QByteArray &s)
852 { return prepend(QString::fromUtf8(s)); }
853 inline QT_ASCII_CAST_WARN QString &append(const char *s)
854 { return append(QString::fromUtf8(s)); }
855 inline QT_ASCII_CAST_WARN QString &append(const QByteArray &s)
856 { return append(QString::fromUtf8(s)); }
857 inline QT_ASCII_CAST_WARN QString &insert(int i, const char *s)
858 { return insert(i, QString::fromUtf8(s)); }
859 inline QT_ASCII_CAST_WARN QString &insert(int i, const QByteArray &s)
860 { return insert(i, QString::fromUtf8(s)); }
861 inline QT_ASCII_CAST_WARN QString &operator+=(const char *s)
862 { return append(QString::fromUtf8(s)); }
863 inline QT_ASCII_CAST_WARN QString &operator+=(const QByteArray &s)
864 { return append(QString::fromUtf8(s)); }
865 inline QT_ASCII_CAST_WARN QString &operator+=(char c)
866 { return append(QChar::fromLatin1(c)); }
867
868 inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
869 inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
870 inline QT_ASCII_CAST_WARN bool operator<(const char *s) const;
871 inline QT_ASCII_CAST_WARN bool operator<=(const char *s) const;
872 inline QT_ASCII_CAST_WARN bool operator>(const char *s) const;
873 inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const;
874
875 inline QT_ASCII_CAST_WARN bool operator==(const QByteArray &s) const;
876 inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &s) const;
877 inline QT_ASCII_CAST_WARN bool operator<(const QByteArray &s) const;
878 inline QT_ASCII_CAST_WARN bool operator>(const QByteArray &s) const;
879 inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &s) const;
880 inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &s) const;
881
882 friend inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QString &s2);
883 friend inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QString &s2);
884 friend inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QString &s2);
885 friend inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QString &s2);
886 friend inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QString &s2);
887 friend inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QString &s2);
888
889 friend inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QStringRef &s2);
890 friend inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QStringRef &s2);
891 friend inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QStringRef &s2);
892 friend inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QStringRef &s2);
893 friend inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QStringRef &s2);
894 friend inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2);
895#endif
896
897 typedef QChar *iterator;
898 typedef const QChar *const_iterator;
899 typedef iterator Iterator;
900 typedef const_iterator ConstIterator;
901 typedef std::reverse_iterator<iterator> reverse_iterator;
902 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
903 inline iterator begin();
904 inline const_iterator begin() const;
905 inline const_iterator cbegin() const;
906 inline const_iterator constBegin() const;
907 inline iterator end();
908 inline const_iterator end() const;
909 inline const_iterator cend() const;
910 inline const_iterator constEnd() const;
911 reverse_iterator rbegin() { return reverse_iterator(end()); }
912 reverse_iterator rend() { return reverse_iterator(begin()); }
913 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
914 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
915 const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
916 const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
917
918 // STL compatibility
919 typedef int size_type;
920 typedef qptrdiff difference_type;
921 typedef const QChar & const_reference;
922 typedef QChar & reference;
923 typedef QChar *pointer;
924 typedef const QChar *const_pointer;
925 typedef QChar value_type;
926 inline void push_back(QChar c) { append(c); }
927 inline void push_back(const QString &s) { append(s); }
928 inline void push_front(QChar c) { prepend(c); }
929 inline void push_front(const QString &s) { prepend(s); }
930 void shrink_to_fit() { squeeze(); }
931
932 static inline QString fromStdString(const std::string &s);
933 inline std::string toStdString() const;
934 static inline QString fromStdWString(const std::wstring &s);
935 inline std::wstring toStdWString() const;
936
937#if defined(Q_STDLIB_UNICODE_STRINGS) || defined(Q_QDOC)
938 static inline QString fromStdU16String(const std::u16string &s);
939 inline std::u16string toStdU16String() const;
940 static inline QString fromStdU32String(const std::u32string &s);
941 inline std::u32string toStdU32String() const;
942#endif
943
944#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
945 static QString fromCFString(CFStringRef string);
946 CFStringRef toCFString() const Q_DECL_CF_RETURNS_RETAINED;
947 static QString fromNSString(const NSString *string);
948 NSString *toNSString() const Q_DECL_NS_RETURNS_AUTORELEASED;
949#endif
950 // compatibility
951#if QT_DEPRECATED_SINCE(5, 9)
952 struct Null { };
953 QT_DEPRECATED_X("use QString()")
954 static const Null null;
955 inline QString(const Null &): d(Data::sharedNull()) {}
956 inline QString &operator=(const Null &) { *this = QString(); return *this; }
957#endif
958 inline bool isNull() const { return d == Data::sharedNull(); }
959
960
961 bool isSimpleText() const;
962 bool isRightToLeft() const;
963 Q_REQUIRED_RESULT bool isValidUtf16() const noexcept
964 { return QStringView(*this).isValidUtf16(); }
965
966 QString(int size, Qt::Initialization);
967 Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {}
968
969private:
970#if defined(QT_NO_CAST_FROM_ASCII)
971 QString &operator+=(const char *s);
972 QString &operator+=(const QByteArray &s);
973 QString(const char *ch);
974 QString(const QByteArray &a);
975 QString &operator=(const char *ch);
976 QString &operator=(const QByteArray &a);
977#endif
978
979 Data *d;
980
981 friend inline bool operator==(QChar, const QString &) noexcept;
982 friend inline bool operator< (QChar, const QString &) noexcept;
983 friend inline bool operator> (QChar, const QString &) noexcept;
984 friend inline bool operator==(QChar, const QStringRef &) noexcept;
985 friend inline bool operator< (QChar, const QStringRef &) noexcept;
986 friend inline bool operator> (QChar, const QStringRef &) noexcept;
987 friend inline bool operator==(QChar, QLatin1String) noexcept;
988 friend inline bool operator< (QChar, QLatin1String) noexcept;
989 friend inline bool operator> (QChar, QLatin1String) noexcept;
990
991 void reallocData(uint alloc, bool grow = false);
992#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
993 void expand(int i);
994 QString multiArg(int numArgs, const QString **args) const;
995#endif
996 static int compare_helper(const QChar *data1, int length1,
997 const QChar *data2, int length2,
998 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
999 static int compare_helper(const QChar *data1, int length1,
1000 const char *data2, int length2,
1001 Qt::CaseSensitivity cs = Qt::CaseSensitive);
1002 static int compare_helper(const QChar *data1, int length1,
1003 QLatin1String s2,
1004 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
1005 static int localeAwareCompare_helper(const QChar *data1, int length1,
1006 const QChar *data2, int length2);
1007 static QString toLower_helper(const QString &str);
1008 static QString toLower_helper(QString &str);
1009 static QString toUpper_helper(const QString &str);
1010 static QString toUpper_helper(QString &str);
1011 static QString toCaseFolded_helper(const QString &str);
1012 static QString toCaseFolded_helper(QString &str);
1013 static QString trimmed_helper(const QString &str);
1014 static QString trimmed_helper(QString &str);
1015 static QString simplified_helper(const QString &str);
1016 static QString simplified_helper(QString &str);
1017 static Data *fromLatin1_helper(const char *str, int size = -1);
1018 static Data *fromAscii_helper(const char *str, int size = -1);
1019 static QString fromUtf8_helper(const char *str, int size);
1020 static QString fromLocal8Bit_helper(const char *, int size);
1021 static QByteArray toLatin1_helper(const QString &);
1022 static QByteArray toLatin1_helper_inplace(QString &);
1023 static QByteArray toUtf8_helper(const QString &);
1024 static QByteArray toLocal8Bit_helper(const QChar *data, int size);
1025 static int toUcs4_helper(const ushort *uc, int length, uint *out);
1026 static qlonglong toIntegral_helper(const QChar *data, int len, bool *ok, int base);
1027 static qulonglong toIntegral_helper(const QChar *data, uint len, bool *ok, int base);
1028 void replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen);
1029 friend class QCharRef;
1030 friend class QTextCodec;
1031 friend class QStringRef;
1032 friend class QStringView;
1033 friend class QByteArray;
1034 friend class QCollator;
1035 friend struct QAbstractConcatenable;
1036
1037 template <typename T> static
1038 T toIntegral_helper(const QChar *data, int len, bool *ok, int base)
1039 {
1040 using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
1041 using Int32 = typename std::conditional<std::is_unsigned<T>::value, uint, int>::type;
1042
1043 // we select the right overload by casting size() to int or uint
1044 Int64 val = toIntegral_helper(data, Int32(len), ok, base);
1045 if (T(val) != val) {
1046 if (ok)
1047 *ok = false;
1048 val = 0;
1049 }
1050 return T(val);
1051 }
1052
1053public:
1054 typedef Data * DataPtr;
1055 inline DataPtr &data_ptr() { return d; }
1056};
1057
1058//
1059// QStringView inline members that require QString:
1060//
1061QString QStringView::toString() const
1062{ return Q_ASSERT(size() == length()), QString(data(), length()); }
1063
1064//
1065// QString inline members
1066//
1067inline QString::QString(QLatin1String aLatin1) : d(fromLatin1_helper(aLatin1.latin1(), aLatin1.size()))
1068{ }
1069inline int QString::length() const
1070{ return d->size; }
1071inline const QChar QString::at(int i) const
1072{ Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); }
1073inline const QChar QString::operator[](int i) const
1074{ Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); }
1075inline const QChar QString::operator[](uint i) const
1076{ Q_ASSERT(i < uint(size())); return QChar(d->data()[i]); }
1077inline bool QString::isEmpty() const
1078{ return d->size == 0; }
1079inline const QChar *QString::unicode() const
1080{ return reinterpret_cast<const QChar*>(d->data()); }
1081inline const QChar *QString::data() const
1082{ return reinterpret_cast<const QChar*>(d->data()); }
1083inline QChar *QString::data()
1084{ detach(); return reinterpret_cast<QChar*>(d->data()); }
1085inline const QChar *QString::constData() const
1086{ return reinterpret_cast<const QChar*>(d->data()); }
1087inline void QString::detach()
1088{ if (d->ref.isShared() || (d->offset != sizeof(QStringData))) reallocData(uint(d->size) + 1u); }
1089inline bool QString::isDetached() const
1090{ return !d->ref.isShared(); }
1091inline void QString::clear()
1092{ if (!isNull()) *this = QString(); }
1093inline QString::QString(const QString &other) noexcept : d(other.d)
1094{ Q_ASSERT(&other != this); d->ref.ref(); }
1095inline int QString::capacity() const
1096{ return d->alloc ? d->alloc - 1 : 0; }
1097inline QString &QString::setNum(short n, int base)
1098{ return setNum(qlonglong(n), base); }
1099inline QString &QString::setNum(ushort n, int base)
1100{ return setNum(qulonglong(n), base); }
1101inline QString &QString::setNum(int n, int base)
1102{ return setNum(qlonglong(n), base); }
1103inline QString &QString::setNum(uint n, int base)
1104{ return setNum(qulonglong(n), base); }
1105inline QString &QString::setNum(long n, int base)
1106{ return setNum(qlonglong(n), base); }
1107inline QString &QString::setNum(ulong n, int base)
1108{ return setNum(qulonglong(n), base); }
1109inline QString &QString::setNum(float n, char f, int prec)
1110{ return setNum(double(n),f,prec); }
1111inline QString QString::arg(int a, int fieldWidth, int base, QChar fillChar) const
1112{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
1113inline QString QString::arg(uint a, int fieldWidth, int base, QChar fillChar) const
1114{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
1115inline QString QString::arg(long a, int fieldWidth, int base, QChar fillChar) const
1116{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
1117inline QString QString::arg(ulong a, int fieldWidth, int base, QChar fillChar) const
1118{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
1119inline QString QString::arg(short a, int fieldWidth, int base, QChar fillChar) const
1120{ return arg(qlonglong(a), fieldWidth, base, fillChar); }
1121inline QString QString::arg(ushort a, int fieldWidth, int base, QChar fillChar) const
1122{ return arg(qulonglong(a), fieldWidth, base, fillChar); }
1123#if QT_STRINGVIEW_LEVEL < 2
1124inline QString QString::arg(const QString &a1, const QString &a2) const
1125{ return qToStringViewIgnoringNull(*this).arg(a1, a2); }
1126inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3) const
1127{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3); }
1128inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
1129 const QString &a4) const
1130{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4); }
1131inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
1132 const QString &a4, const QString &a5) const
1133{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5); }
1134inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
1135 const QString &a4, const QString &a5, const QString &a6) const
1136{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6); }
1137inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
1138 const QString &a4, const QString &a5, const QString &a6,
1139 const QString &a7) const
1140{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6, a7); }
1141inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
1142 const QString &a4, const QString &a5, const QString &a6,
1143 const QString &a7, const QString &a8) const
1144{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6, a7, a8); }
1145inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3,
1146 const QString &a4, const QString &a5, const QString &a6,
1147 const QString &a7, const QString &a8, const QString &a9) const
1148{ return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6, a7, a8, a9); }
1149#endif
1150
1151inline QString QString::section(QChar asep, int astart, int aend, SectionFlags aflags) const
1152{ return section(QString(asep), astart, aend, aflags); }
1153
1154QT_WARNING_PUSH
1155QT_WARNING_DISABLE_MSVC(4127) // "conditional expression is constant"
1156QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable"
1157
1158inline int QString::toWCharArray(wchar_t *array) const
1159{
1160 return qToStringViewIgnoringNull(*this).toWCharArray(array);
1161}
1162
1163int QStringView::toWCharArray(wchar_t *array) const
1164{
1165 if (sizeof(wchar_t) == sizeof(QChar)) {
1166 if (auto src = data())
1167 memcpy(array, src, sizeof(QChar) * size());
1168 return int(size()); // ### q6sizetype
1169 } else {
1170 return QString::toUcs4_helper(reinterpret_cast<const ushort *>(data()), int(size()),
1171 reinterpret_cast<uint *>(array));
1172 }
1173}
1174
1175QT_WARNING_POP
1176
1177inline QString QString::fromWCharArray(const wchar_t *string, int size)
1178{
1179 return sizeof(wchar_t) == sizeof(QChar) ? fromUtf16(reinterpret_cast<const ushort *>(string), size)
1180 : fromUcs4(reinterpret_cast<const uint *>(string), size);
1181}
1182
1183class
1184#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1185Q_CORE_EXPORT
1186#endif
1187QCharRef { // ### Qt 7: remove
1188 QString &s;
1189 int i;
1190 inline QCharRef(QString &str, int idx)
1191 : s(str),i(idx) {}
1192 friend class QString;
1193public:
1194 QCharRef(const QCharRef &) = default;
1195
1196 // most QChar operations repeated here
1197
1198 // all this is not documented: We just say "like QChar" and let it be.
1199 inline operator QChar() const
1200 {
1201 using namespace QtPrivate::DeprecatedRefClassBehavior;
1202 if (Q_LIKELY(i < s.d->size))
1203 return QChar(s.d->data()[i]);
1204#ifdef QT_DEBUG
1205 warn(WarningType::OutOfRange, EmittingClass::QCharRef);
1206#endif
1207 return QChar();
1208 }
1209 inline QCharRef &operator=(QChar c)
1210 {
1211 using namespace QtPrivate::DeprecatedRefClassBehavior;
1212 if (Q_UNLIKELY(i >= s.d->size)) {
1213#ifdef QT_DEBUG
1214 warn(WarningType::OutOfRange, EmittingClass::QCharRef);
1215#endif
1216 s.resize(i + 1, QLatin1Char(' '));
1217 } else {
1218#ifdef QT_DEBUG
1219 if (Q_UNLIKELY(!s.isDetached()))
1220 warn(WarningType::DelayedDetach, EmittingClass::QCharRef);
1221#endif
1222 s.detach();
1223 }
1224 s.d->data()[i] = c.unicode();
1225 return *this;
1226 }
1227
1228 // An operator= for each QChar cast constructors
1229#ifndef QT_NO_CAST_FROM_ASCII
1230 inline QT_ASCII_CAST_WARN QCharRef &operator=(char c)
1231 { return operator=(QChar::fromLatin1(c)); }
1232 inline QT_ASCII_CAST_WARN QCharRef &operator=(uchar c)
1233 { return operator=(QChar::fromLatin1(c)); }
1234#else
1235 // prevent char -> int promotion, bypassing QT_NO_CAST_FROM_ASCII
1236 QCharRef &operator=(char c) = delete;
1237 QCharRef &operator=(uchar c) = delete;
1238#endif
1239 inline QCharRef &operator=(const QCharRef &c) { return operator=(QChar(c)); }
1240 inline QCharRef &operator=(ushort rc) { return operator=(QChar(rc)); }
1241 inline QCharRef &operator=(short rc) { return operator=(QChar(rc)); }
1242 inline QCharRef &operator=(uint rc) { return operator=(QChar(rc)); }
1243 inline QCharRef &operator=(int rc) { return operator=(QChar(rc)); }
1244
1245 // each function...
1246 inline bool isNull() const { return QChar(*this).isNull(); }
1247 inline bool isPrint() const { return QChar(*this).isPrint(); }
1248 inline bool isPunct() const { return QChar(*this).isPunct(); }
1249 inline bool isSpace() const { return QChar(*this).isSpace(); }
1250 inline bool isMark() const { return QChar(*this).isMark(); }
1251 inline bool isLetter() const { return QChar(*this).isLetter(); }
1252 inline bool isNumber() const { return QChar(*this).isNumber(); }
1253 inline bool isLetterOrNumber() { return QChar(*this).isLetterOrNumber(); }
1254 inline bool isDigit() const { return QChar(*this).isDigit(); }
1255 inline bool isLower() const { return QChar(*this).isLower(); }
1256 inline bool isUpper() const { return QChar(*this).isUpper(); }
1257 inline bool isTitleCase() const { return QChar(*this).isTitleCase(); }
1258
1259 inline int digitValue() const { return QChar(*this).digitValue(); }
1260 QChar toLower() const { return QChar(*this).toLower(); }
1261 QChar toUpper() const { return QChar(*this).toUpper(); }
1262 QChar toTitleCase () const { return QChar(*this).toTitleCase(); }
1263
1264 QChar::Category category() const { return QChar(*this).category(); }
1265 QChar::Direction direction() const { return QChar(*this).direction(); }
1266 QChar::JoiningType joiningType() const { return QChar(*this).joiningType(); }
1267#if QT_DEPRECATED_SINCE(5, 3)
1268 QT_DEPRECATED QChar::Joining joining() const
1269 {
1270 switch (QChar(*this).joiningType()) {
1271 case QChar::Joining_Causing: return QChar::Center;
1272 case QChar::Joining_Dual: return QChar::Dual;
1273 case QChar::Joining_Right: return QChar::Right;
1274 case QChar::Joining_None:
1275 case QChar::Joining_Left:
1276 case QChar::Joining_Transparent:
1277 default: return QChar::OtherJoining;
1278 }
1279 }
1280#endif
1281 bool hasMirrored() const { return QChar(*this).hasMirrored(); }
1282 QChar mirroredChar() const { return QChar(*this).mirroredChar(); }
1283 QString decomposition() const { return QChar(*this).decomposition(); }
1284 QChar::Decomposition decompositionTag() const { return QChar(*this).decompositionTag(); }
1285 uchar combiningClass() const { return QChar(*this).combiningClass(); }
1286
1287 inline QChar::Script script() const { return QChar(*this).script(); }
1288
1289 QChar::UnicodeVersion unicodeVersion() const { return QChar(*this).unicodeVersion(); }
1290
1291 inline uchar cell() const { return QChar(*this).cell(); }
1292 inline uchar row() const { return QChar(*this).row(); }
1293 inline void setCell(uchar cell);
1294 inline void setRow(uchar row);
1295
1296#if QT_DEPRECATED_SINCE(5, 0)
1297 QT_DEPRECATED char toAscii() const { return QChar(*this).toLatin1(); }
1298#endif
1299 char toLatin1() const { return QChar(*this).toLatin1(); }
1300 ushort unicode() const { return QChar(*this).unicode(); }
1301 ushort& unicode() { return s.data()[i].unicode(); }
1302
1303};
1304Q_DECLARE_TYPEINFO(QCharRef, Q_MOVABLE_TYPE);
1305
1306inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
1307inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
1308
1309
1310inline QString::QString() noexcept : d(Data::sharedNull()) {}
1311inline QString::~QString() { if (!d->ref.deref()) Data::deallocate(d); }
1312
1313inline void QString::reserve(int asize)
1314{
1315 if (d->ref.isShared() || uint(asize) >= d->alloc)
1316 reallocData(qMax(asize, d->size) + 1u);
1317
1318 if (!d->capacityReserved) {
1319 // cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
1320 d->capacityReserved = true;
1321 }
1322}
1323
1324inline void QString::squeeze()
1325{
1326 if (d->ref.isShared() || uint(d->size) + 1u < d->alloc)
1327 reallocData(uint(d->size) + 1u);
1328
1329 if (d->capacityReserved) {
1330 // cannot set unconditionally, since d could be shared_null or
1331 // otherwise static.
1332 d->capacityReserved = false;
1333 }
1334}
1335
1336inline QString &QString::setUtf16(const ushort *autf16, int asize)
1337{ return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
1338inline QCharRef QString::operator[](int i)
1339{ Q_ASSERT(i >= 0); detach(); return QCharRef(*this, i); }
1340inline QCharRef QString::operator[](uint i)
1341{ detach(); return QCharRef(*this, i); }
1342inline QCharRef QString::front() { return operator[](0); }
1343inline QCharRef QString::back() { return operator[](size() - 1); }
1344inline QString::iterator QString::begin()
1345{ detach(); return reinterpret_cast<QChar*>(d->data()); }
1346inline QString::const_iterator QString::begin() const
1347{ return reinterpret_cast<const QChar*>(d->data()); }
1348inline QString::const_iterator QString::cbegin() const
1349{ return reinterpret_cast<const QChar*>(d->data()); }
1350inline QString::const_iterator QString::constBegin() const
1351{ return reinterpret_cast<const QChar*>(d->data()); }
1352inline QString::iterator QString::end()
1353{ detach(); return reinterpret_cast<QChar*>(d->data() + d->size); }
1354inline QString::const_iterator QString::end() const
1355{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
1356inline QString::const_iterator QString::cend() const
1357{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
1358inline QString::const_iterator QString::constEnd() const
1359{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
1360#if QT_STRINGVIEW_LEVEL < 2
1361inline bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
1362{ return indexOf(s, 0, cs) != -1; }
1363inline bool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
1364{ return indexOf(s, 0, cs) != -1; }
1365#endif
1366inline bool QString::contains(QLatin1String s, Qt::CaseSensitivity cs) const
1367{ return indexOf(s, 0, cs) != -1; }
1368inline bool QString::contains(QChar c, Qt::CaseSensitivity cs) const
1369{ return indexOf(c, 0, cs) != -1; }
1370inline bool QString::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
1371{ return indexOf(s, 0, cs) != -1; }
1372
1373#if QT_DEPRECATED_SINCE(5, 9)
1374inline bool operator==(QString::Null, QString::Null) { return true; }
1375QT_DEPRECATED_X("use QString::isNull()")
1376inline bool operator==(QString::Null, const QString &s) { return s.isNull(); }
1377QT_DEPRECATED_X("use QString::isNull()")
1378inline bool operator==(const QString &s, QString::Null) { return s.isNull(); }
1379inline bool operator!=(QString::Null, QString::Null) { return false; }
1380QT_DEPRECATED_X("use !QString::isNull()")
1381inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); }
1382QT_DEPRECATED_X("use !QString::isNull()")
1383inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); }
1384#endif
1385
1386inline bool operator==(QLatin1String s1, QLatin1String s2) noexcept
1387{ return s1.size() == s2.size() && (!s1.size() || !memcmp(s1.latin1(), s2.latin1(), s1.size())); }
1388inline bool operator!=(QLatin1String s1, QLatin1String s2) noexcept
1389{ return !operator==(s1, s2); }
1390inline bool operator<(QLatin1String s1, QLatin1String s2) noexcept
1391{
1392 const int len = qMin(s1.size(), s2.size());
1393 const int r = len ? memcmp(s1.latin1(), s2.latin1(), len) : 0;
1394 return r < 0 || (r == 0 && s1.size() < s2.size());
1395}
1396inline bool operator>(QLatin1String s1, QLatin1String s2) noexcept
1397{ return operator<(s2, s1); }
1398inline bool operator<=(QLatin1String s1, QLatin1String s2) noexcept
1399{ return !operator>(s1, s2); }
1400inline bool operator>=(QLatin1String s1, QLatin1String s2) noexcept
1401{ return !operator<(s1, s2); }
1402
1403inline bool QLatin1String::operator==(const QString &s) const noexcept
1404{ return s == *this; }
1405inline bool QLatin1String::operator!=(const QString &s) const noexcept
1406{ return s != *this; }
1407inline bool QLatin1String::operator>(const QString &s) const noexcept
1408{ return s < *this; }
1409inline bool QLatin1String::operator<(const QString &s) const noexcept
1410{ return s > *this; }
1411inline bool QLatin1String::operator>=(const QString &s) const noexcept
1412{ return s <= *this; }
1413inline bool QLatin1String::operator<=(const QString &s) const noexcept
1414{ return s >= *this; }
1415
1416#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1417inline bool QString::operator==(const char *s) const
1418{ return QString::compare_helper(constData(), size(), s, -1) == 0; }
1419inline bool QString::operator!=(const char *s) const
1420{ return QString::compare_helper(constData(), size(), s, -1) != 0; }
1421inline bool QString::operator<(const char *s) const
1422{ return QString::compare_helper(constData(), size(), s, -1) < 0; }
1423inline bool QString::operator>(const char *s) const
1424{ return QString::compare_helper(constData(), size(), s, -1) > 0; }
1425inline bool QString::operator<=(const char *s) const
1426{ return QString::compare_helper(constData(), size(), s, -1) <= 0; }
1427inline bool QString::operator>=(const char *s) const
1428{ return QString::compare_helper(constData(), size(), s, -1) >= 0; }
1429
1430inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QString &s2)
1431{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) == 0; }
1432inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QString &s2)
1433{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) != 0; }
1434inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QString &s2)
1435{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) > 0; }
1436inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QString &s2)
1437{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) < 0; }
1438inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QString &s2)
1439{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
1440inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QString &s2)
1441{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; }
1442
1443inline QT_ASCII_CAST_WARN bool operator==(const char *s1, QLatin1String s2)
1444{ return QString::fromUtf8(s1) == s2; }
1445inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, QLatin1String s2)
1446{ return QString::fromUtf8(s1) != s2; }
1447inline QT_ASCII_CAST_WARN bool operator<(const char *s1, QLatin1String s2)
1448{ return (QString::fromUtf8(s1) < s2); }
1449inline QT_ASCII_CAST_WARN bool operator>(const char *s1, QLatin1String s2)
1450{ return (QString::fromUtf8(s1) > s2); }
1451inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, QLatin1String s2)
1452{ return (QString::fromUtf8(s1) <= s2); }
1453inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, QLatin1String s2)
1454{ return (QString::fromUtf8(s1) >= s2); }
1455
1456inline QT_ASCII_CAST_WARN bool QLatin1String::operator==(const char *s) const
1457{ return QString::fromUtf8(s) == *this; }
1458inline QT_ASCII_CAST_WARN bool QLatin1String::operator!=(const char *s) const
1459{ return QString::fromUtf8(s) != *this; }
1460inline QT_ASCII_CAST_WARN bool QLatin1String::operator<(const char *s) const
1461{ return QString::fromUtf8(s) > *this; }
1462inline QT_ASCII_CAST_WARN bool QLatin1String::operator>(const char *s) const
1463{ return QString::fromUtf8(s) < *this; }
1464inline QT_ASCII_CAST_WARN bool QLatin1String::operator<=(const char *s) const
1465{ return QString::fromUtf8(s) >= *this; }
1466inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const char *s) const
1467{ return QString::fromUtf8(s) <= *this; }
1468
1469inline QT_ASCII_CAST_WARN bool QLatin1String::operator==(const QByteArray &s) const
1470{ return QString::fromUtf8(s) == *this; }
1471inline QT_ASCII_CAST_WARN bool QLatin1String::operator!=(const QByteArray &s) const
1472{ return QString::fromUtf8(s) != *this; }
1473inline QT_ASCII_CAST_WARN bool QLatin1String::operator<(const QByteArray &s) const
1474{ return QString::fromUtf8(s) > *this; }
1475inline QT_ASCII_CAST_WARN bool QLatin1String::operator>(const QByteArray &s) const
1476{ return QString::fromUtf8(s) < *this; }
1477inline QT_ASCII_CAST_WARN bool QLatin1String::operator<=(const QByteArray &s) const
1478{ return QString::fromUtf8(s) >= *this; }
1479inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const QByteArray &s) const
1480{ return QString::fromUtf8(s) <= *this; }
1481
1482inline QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const
1483{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) == 0; }
1484inline QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const
1485{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) != 0; }
1486inline QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const
1487{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; }
1488inline QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const
1489{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) > 0; }
1490inline QT_ASCII_CAST_WARN bool QString::operator<=(const QByteArray &s) const
1491{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) <= 0; }
1492inline QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const
1493{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; }
1494
1495inline bool QByteArray::operator==(const QString &s) const
1496{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) == 0; }
1497inline bool QByteArray::operator!=(const QString &s) const
1498{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) != 0; }
1499inline bool QByteArray::operator<(const QString &s) const
1500{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; }
1501inline bool QByteArray::operator>(const QString &s) const
1502{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) < 0; }
1503inline bool QByteArray::operator<=(const QString &s) const
1504{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) >= 0; }
1505inline bool QByteArray::operator>=(const QString &s) const
1506{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) <= 0; }
1507
1508#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1509
1510#if !defined(QT_NO_CAST_TO_ASCII) && QT_DEPRECATED_SINCE(5, 15)
1511inline QByteArray &QByteArray::append(const QString &s)
1512{ return append(s.toUtf8()); }
1513inline QByteArray &QByteArray::insert(int i, const QString &s)
1514{ return insert(i, s.toUtf8()); }
1515inline QByteArray &QByteArray::replace(char c, const QString &after)
1516{ return replace(c, after.toUtf8()); }
1517inline QByteArray &QByteArray::replace(const QString &before, const char *after)
1518{ return replace(before.toUtf8(), after); }
1519inline QByteArray &QByteArray::replace(const QString &before, const QByteArray &after)
1520{ return replace(before.toUtf8(), after); }
1521inline QByteArray &QByteArray::operator+=(const QString &s)
1522{ return operator+=(s.toUtf8()); }
1523inline int QByteArray::indexOf(const QString &s, int from) const
1524{ return indexOf(s.toUtf8(), from); }
1525inline int QByteArray::lastIndexOf(const QString &s, int from) const
1526{ return lastIndexOf(s.toUtf8(), from); }
1527#endif // !defined(QT_NO_CAST_TO_ASCII) && QT_DEPRECATED_SINCE(5, 15)
1528
1529#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
1530inline const QString operator+(const QString &s1, const QString &s2)
1531{ QString t(s1); t += s2; return t; }
1532inline const QString operator+(const QString &s1, QChar s2)
1533{ QString t(s1); t += s2; return t; }
1534inline const QString operator+(QChar s1, const QString &s2)
1535{ QString t(s1); t += s2; return t; }
1536# if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1537inline QT_ASCII_CAST_WARN const QString operator+(const QString &s1, const char *s2)
1538{ QString t(s1); t += QString::fromUtf8(s2); return t; }
1539inline QT_ASCII_CAST_WARN const QString operator+(const char *s1, const QString &s2)
1540{ QString t = QString::fromUtf8(s1); t += s2; return t; }
1541inline QT_ASCII_CAST_WARN const QString operator+(char c, const QString &s)
1542{ QString t = s; t.prepend(QChar::fromLatin1(c)); return t; }
1543inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, char c)
1544{ QString t = s; t += QChar::fromLatin1(c); return t; }
1545inline QT_ASCII_CAST_WARN const QString operator+(const QByteArray &ba, const QString &s)
1546{ QString t = QString::fromUtf8(ba); t += s; return t; }
1547inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, const QByteArray &ba)
1548{ QString t(s); t += QString::fromUtf8(ba); return t; }
1549# endif // QT_NO_CAST_FROM_ASCII
1550#endif // QT_USE_QSTRINGBUILDER
1551
1552inline std::string QString::toStdString() const
1553{ return toUtf8().toStdString(); }
1554
1555inline QString QString::fromStdString(const std::string &s)
1556{ return fromUtf8(s.data(), int(s.size())); }
1557
1558inline std::wstring QString::toStdWString() const
1559{
1560 std::wstring str;
1561 str.resize(length());
1562#if __cplusplus >= 201703L
1563 str.resize(toWCharArray(str.data()));
1564#else
1565 if (length())
1566 str.resize(toWCharArray(&str.front()));
1567#endif
1568 return str;
1569}
1570
1571inline QString QString::fromStdWString(const std::wstring &s)
1572{ return fromWCharArray(s.data(), int(s.size())); }
1573
1574#if defined(Q_STDLIB_UNICODE_STRINGS)
1575inline QString QString::fromStdU16String(const std::u16string &s)
1576{ return fromUtf16(s.data(), int(s.size())); }
1577
1578inline std::u16string QString::toStdU16String() const
1579{ return std::u16string(reinterpret_cast<const char16_t*>(utf16()), length()); }
1580
1581inline QString QString::fromStdU32String(const std::u32string &s)
1582{ return fromUcs4(s.data(), int(s.size())); }
1583
1584inline std::u32string QString::toStdU32String() const
1585{
1586 std::u32string u32str(length(), char32_t(0));
1587 int len = toUcs4_helper(d->data(), length(), reinterpret_cast<uint*>(&u32str[0]));
1588 u32str.resize(len);
1589 return u32str;
1590}
1591#endif
1592
1593#if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
1594Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QString &);
1595Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QString &);
1596#endif
1597
1598Q_DECLARE_SHARED(QString)
1599Q_DECLARE_OPERATORS_FOR_FLAGS(QString::SectionFlags)
1600
1601
1602class Q_CORE_EXPORT QStringRef {
1603 const QString *m_string;
1604 int m_position;
1605 int m_size;
1606public:
1607 typedef QString::size_type size_type;
1608 typedef QString::value_type value_type;
1609 typedef const QChar *const_iterator;
1610 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1611 typedef QString::const_pointer const_pointer;
1612 typedef QString::const_reference const_reference;
1613
1614 // ### Qt 6: make this constructor constexpr, after the destructor is made trivial
1615 inline QStringRef() : m_string(nullptr), m_position(0), m_size(0) {}
1616 inline QStringRef(const QString *string, int position, int size);
1617 inline QStringRef(const QString *string);
1618
1619#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1620 // ### Qt 6: remove all of these, the implicit ones are fine
1621 QStringRef(const QStringRef &other) noexcept
1622 :m_string(other.m_string), m_position(other.m_position), m_size(other.m_size)
1623 {}
1624 QStringRef(QStringRef &&other) noexcept : m_string(other.m_string), m_position(other.m_position), m_size(other.m_size) {}
1625 QStringRef &operator=(QStringRef &&other) noexcept { return *this = other; }
1626 QStringRef &operator=(const QStringRef &other) noexcept
1627 {
1628 m_string = other.m_string; m_position = other.m_position;
1629 m_size = other.m_size; return *this;
1630 }
1631 inline ~QStringRef(){}
1632#endif // Qt < 6.0.0
1633
1634 inline const QString *string() const { return m_string; }
1635 inline int position() const { return m_position; }
1636 inline int size() const { return m_size; }
1637 inline int count() const { return m_size; }
1638 inline int length() const { return m_size; }
1639
1640#if QT_STRINGVIEW_LEVEL < 2
1641 int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1642 int indexOf(const QStringRef &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1643#endif
1644 Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1645 { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
1646 int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1647 int indexOf(QLatin1String str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1648#if QT_STRINGVIEW_LEVEL < 2
1649 int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1650 int lastIndexOf(const QString &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1651#endif
1652 int lastIndexOf(QChar ch, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1653 int lastIndexOf(QLatin1String str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1654 Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1655 { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
1656
1657#if QT_STRINGVIEW_LEVEL < 2
1658 inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1659 inline bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1660#endif
1661 inline bool contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1662 inline bool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1663 inline bool contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1664
1665 int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1666 int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1667 int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1668
1669#if QT_DEPRECATED_SINCE(5, 15)
1670 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use Qt::SplitBehavior variant instead")
1671 QVector<QStringRef> split(const QString &sep, QString::SplitBehavior behavior,
1672 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1673 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use Qt::SplitBehavior variant instead")
1674 QVector<QStringRef> split(QChar sep, QString::SplitBehavior behavior,
1675 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1676#endif // 5.15 deprecations
1677
1678 Q_REQUIRED_RESULT
1679 QVector<QStringRef> split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
1680 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1681 Q_REQUIRED_RESULT
1682 QVector<QStringRef> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
1683 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1684
1685 Q_REQUIRED_RESULT QStringRef left(int n) const;
1686 Q_REQUIRED_RESULT QStringRef right(int n) const;
1687 Q_REQUIRED_RESULT QStringRef mid(int pos, int n = -1) const;
1688 Q_REQUIRED_RESULT QStringRef chopped(int n) const
1689 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return left(size() - n); }
1690
1691 void truncate(int pos) noexcept { m_size = qBound(0, pos, m_size); }
1692 void chop(int n) noexcept
1693 {
1694 if (n >= m_size)
1695 m_size = 0;
1696 else if (n > 0)
1697 m_size -= n;
1698 }
1699
1700 bool isRightToLeft() const;
1701
1702 Q_REQUIRED_RESULT bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1703 { return QtPrivate::startsWith(*this, s, cs); }
1704 bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1705 bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1706#if QT_STRINGVIEW_LEVEL < 2
1707 bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1708 bool startsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1709#endif
1710
1711 Q_REQUIRED_RESULT bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1712 { return QtPrivate::endsWith(*this, s, cs); }
1713 bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1714 bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1715#if QT_STRINGVIEW_LEVEL < 2
1716 bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1717 bool endsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1718#endif
1719
1720 inline QStringRef &operator=(const QString *string);
1721
1722 inline const QChar *unicode() const
1723 {
1724 if (!m_string)
1725 return reinterpret_cast<const QChar *>(QString::Data::sharedNull()->data());
1726 return m_string->unicode() + m_position;
1727 }
1728 inline const QChar *data() const { return unicode(); }
1729 inline const QChar *constData() const { return unicode(); }
1730
1731 inline const_iterator begin() const { return unicode(); }
1732 inline const_iterator cbegin() const { return unicode(); }
1733 inline const_iterator constBegin() const { return unicode(); }
1734 inline const_iterator end() const { return unicode() + size(); }
1735 inline const_iterator cend() const { return unicode() + size(); }
1736 inline const_iterator constEnd() const { return unicode() + size(); }
1737 inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
1738 inline const_reverse_iterator crbegin() const { return rbegin(); }
1739 inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
1740 inline const_reverse_iterator crend() const { return rend(); }
1741
1742#if QT_DEPRECATED_SINCE(5, 0)
1743 Q_REQUIRED_RESULT QT_DEPRECATED QByteArray toAscii() const
1744 { return toLatin1(); }
1745#endif
1746 Q_REQUIRED_RESULT QByteArray toLatin1() const;
1747 Q_REQUIRED_RESULT QByteArray toUtf8() const;
1748 Q_REQUIRED_RESULT QByteArray toLocal8Bit() const;
1749 Q_REQUIRED_RESULT QVector<uint> toUcs4() const;
1750
1751 inline void clear() { m_string = nullptr; m_position = m_size = 0; }
1752 QString toString() const;
1753 inline bool isEmpty() const { return m_size == 0; }
1754 inline bool isNull() const { return m_string == nullptr || m_string->isNull(); }
1755
1756 QStringRef appendTo(QString *string) const;
1757
1758 inline const QChar at(int i) const
1759 { Q_ASSERT(uint(i) < uint(size())); return m_string->at(i + m_position); }
1760 QChar operator[](int i) const { return at(i); }
1761 Q_REQUIRED_RESULT QChar front() const { return at(0); }
1762 Q_REQUIRED_RESULT QChar back() const { return at(size() - 1); }
1763
1764#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1765 // ASCII compatibility
1766 inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
1767 inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
1768 inline QT_ASCII_CAST_WARN bool operator<(const char *s) const;
1769 inline QT_ASCII_CAST_WARN bool operator<=(const char *s) const;
1770 inline QT_ASCII_CAST_WARN bool operator>(const char *s) const;
1771 inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const;
1772#endif
1773
1774 int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1775 int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1776 int compare(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1777 { return QtPrivate::compareStrings(*this, QStringView(&c, 1), cs); }
1778 int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1779#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1780 int compare(const QByteArray &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
1781 { return QString::compare_helper(unicode(), size(), s.data(), qstrnlen(s.data(), s.size()), cs); }
1782#endif
1783 static int compare(const QStringRef &s1, const QString &s2,
1784 Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
1785 static int compare(const QStringRef &s1, const QStringRef &s2,
1786 Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
1787 static int compare(const QStringRef &s1, QLatin1String s2,
1788 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
1789
1790 int localeAwareCompare(const QString &s) const;
1791 int localeAwareCompare(const QStringRef &s) const;
1792 int localeAwareCompare(QStringView str) const;
1793 static int localeAwareCompare(const QStringRef &s1, const QString &s2);
1794 static int localeAwareCompare(const QStringRef &s1, const QStringRef &s2);
1795 static int localeAwareCompare(QStringView s1, QStringView s2);
1796
1797 Q_REQUIRED_RESULT QStringRef trimmed() const;
1798 short toShort(bool *ok = nullptr, int base = 10) const;
1799 ushort toUShort(bool *ok = nullptr, int base = 10) const;
1800 int toInt(bool *ok = nullptr, int base = 10) const;
1801 uint toUInt(bool *ok = nullptr, int base = 10) const;
1802 long toLong(bool *ok = nullptr, int base = 10) const;
1803 ulong toULong(bool *ok = nullptr, int base = 10) const;
1804 qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
1805 qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
1806 float toFloat(bool *ok = nullptr) const;
1807 double toDouble(bool *ok = nullptr) const;
1808};
1809Q_DECLARE_TYPEINFO(QStringRef, Q_PRIMITIVE_TYPE);
1810
1811inline QStringRef &QStringRef::operator=(const QString *aString)
1812{ m_string = aString; m_position = 0; m_size = aString?aString->size():0; return *this; }
1813
1814inline QStringRef::QStringRef(const QString *aString, int aPosition, int aSize)
1815 :m_string(aString), m_position(aPosition), m_size(aSize){}
1816
1817inline QStringRef::QStringRef(const QString *aString)
1818 :m_string(aString), m_position(0), m_size(aString?aString->size() : 0){}
1819
1820// QStringRef <> QStringRef
1821Q_CORE_EXPORT bool operator==(const QStringRef &s1, const QStringRef &s2) noexcept;
1822inline bool operator!=(const QStringRef &s1, const QStringRef &s2) noexcept
1823{ return !(s1 == s2); }
1824Q_CORE_EXPORT bool operator<(const QStringRef &s1, const QStringRef &s2) noexcept;
1825inline bool operator>(const QStringRef &s1, const QStringRef &s2) noexcept
1826{ return s2 < s1; }
1827inline bool operator<=(const QStringRef &s1, const QStringRef &s2) noexcept
1828{ return !(s1 > s2); }
1829inline bool operator>=(const QStringRef &s1, const QStringRef &s2) noexcept
1830{ return !(s1 < s2); }
1831
1832// QString <> QStringRef
1833Q_CORE_EXPORT bool operator==(const QString &lhs, const QStringRef &rhs) noexcept;
1834inline bool operator!=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) != 0; }
1835inline bool operator< (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) < 0; }
1836inline bool operator> (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) > 0; }
1837inline bool operator<=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) <= 0; }
1838inline bool operator>=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) >= 0; }
1839
1840inline bool operator==(const QStringRef &lhs, const QString &rhs) noexcept { return rhs == lhs; }
1841inline bool operator!=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs != lhs; }
1842inline bool operator< (const QStringRef &lhs, const QString &rhs) noexcept { return rhs > lhs; }
1843inline bool operator> (const QStringRef &lhs, const QString &rhs) noexcept { return rhs < lhs; }
1844inline bool operator<=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs >= lhs; }
1845inline bool operator>=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs <= lhs; }
1846
1847#if QT_STRINGVIEW_LEVEL < 2
1848inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const noexcept
1849{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
1850#endif
1851inline int QString::compare(QStringView s, Qt::CaseSensitivity cs) const noexcept
1852{ return -s.compare(*this, cs); }
1853inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs) noexcept
1854{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
1855inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const noexcept
1856{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
1857inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const noexcept
1858{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
1859inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
1860{ return QString::compare_helper(constData(), length(), s, cs); }
1861inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs) noexcept
1862{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
1863inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs) noexcept
1864{ return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
1865inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs) noexcept
1866{ return QString::compare_helper(s1.constData(), s1.length(), s2, cs); }
1867
1868// QLatin1String <> QStringRef
1869Q_CORE_EXPORT bool operator==(QLatin1String lhs, const QStringRef &rhs) noexcept;
1870inline bool operator!=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) != 0; }
1871inline bool operator< (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) > 0; }
1872inline bool operator> (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) < 0; }
1873inline bool operator<=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) >= 0; }
1874inline bool operator>=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) <= 0; }
1875
1876inline bool operator==(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs == lhs; }
1877inline bool operator!=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs != lhs; }
1878inline bool operator< (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs > lhs; }
1879inline bool operator> (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs < lhs; }
1880inline bool operator<=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs >= lhs; }
1881inline bool operator>=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs <= lhs; }
1882
1883// QChar <> QString
1884inline bool operator==(QChar lhs, const QString &rhs) noexcept
1885{ return rhs.size() == 1 && lhs == rhs.front(); }
1886inline bool operator< (QChar lhs, const QString &rhs) noexcept
1887{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; }
1888inline bool operator> (QChar lhs, const QString &rhs) noexcept
1889{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; }
1890
1891inline bool operator!=(QChar lhs, const QString &rhs) noexcept { return !(lhs == rhs); }
1892inline bool operator<=(QChar lhs, const QString &rhs) noexcept { return !(lhs > rhs); }
1893inline bool operator>=(QChar lhs, const QString &rhs) noexcept { return !(lhs < rhs); }
1894
1895inline bool operator==(const QString &lhs, QChar rhs) noexcept { return rhs == lhs; }
1896inline bool operator!=(const QString &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
1897inline bool operator< (const QString &lhs, QChar rhs) noexcept { return rhs > lhs; }
1898inline bool operator> (const QString &lhs, QChar rhs) noexcept { return rhs < lhs; }
1899inline bool operator<=(const QString &lhs, QChar rhs) noexcept { return !(rhs < lhs); }
1900inline bool operator>=(const QString &lhs, QChar rhs) noexcept { return !(rhs > lhs); }
1901
1902// QChar <> QStringRef
1903inline bool operator==(QChar lhs, const QStringRef &rhs) noexcept
1904{ return rhs.size() == 1 && lhs == rhs.front(); }
1905inline bool operator< (QChar lhs, const QStringRef &rhs) noexcept
1906{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; }
1907inline bool operator> (QChar lhs, const QStringRef &rhs) noexcept
1908{ return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; }
1909
1910inline bool operator!=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs == rhs); }
1911inline bool operator<=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs > rhs); }
1912inline bool operator>=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs < rhs); }
1913
1914inline bool operator==(const QStringRef &lhs, QChar rhs) noexcept { return rhs == lhs; }
1915inline bool operator!=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
1916inline bool operator< (const QStringRef &lhs, QChar rhs) noexcept { return rhs > lhs; }
1917inline bool operator> (const QStringRef &lhs, QChar rhs) noexcept { return rhs < lhs; }
1918inline bool operator<=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs < lhs); }
1919inline bool operator>=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs > lhs); }
1920
1921// QChar <> QLatin1String
1922inline bool operator==(QChar lhs, QLatin1String rhs) noexcept
1923{ return rhs.size() == 1 && lhs == rhs.front(); }
1924inline bool operator< (QChar lhs, QLatin1String rhs) noexcept
1925{ return QString::compare_helper(&lhs, 1, rhs) < 0; }
1926inline bool operator> (QChar lhs, QLatin1String rhs) noexcept
1927{ return QString::compare_helper(&lhs, 1, rhs) > 0; }
1928
1929inline bool operator!=(QChar lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
1930inline bool operator<=(QChar lhs, QLatin1String rhs) noexcept { return !(lhs > rhs); }
1931inline bool operator>=(QChar lhs, QLatin1String rhs) noexcept { return !(lhs < rhs); }
1932
1933inline bool operator==(QLatin1String lhs, QChar rhs) noexcept { return rhs == lhs; }
1934inline bool operator!=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs == lhs); }
1935inline bool operator< (QLatin1String lhs, QChar rhs) noexcept { return rhs > lhs; }
1936inline bool operator> (QLatin1String lhs, QChar rhs) noexcept { return rhs < lhs; }
1937inline bool operator<=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs < lhs); }
1938inline bool operator>=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs > lhs); }
1939
1940// QStringView <> QStringView
1941inline bool operator==(QStringView lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
1942inline bool operator!=(QStringView lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
1943inline bool operator< (QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
1944inline bool operator<=(QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
1945inline bool operator> (QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
1946inline bool operator>=(QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
1947
1948// QStringView <> QChar
1949inline bool operator==(QStringView lhs, QChar rhs) noexcept { return lhs == QStringView(&rhs, 1); }
1950inline bool operator!=(QStringView lhs, QChar rhs) noexcept { return lhs != QStringView(&rhs, 1); }
1951inline bool operator< (QStringView lhs, QChar rhs) noexcept { return lhs < QStringView(&rhs, 1); }
1952inline bool operator<=(QStringView lhs, QChar rhs) noexcept { return lhs <= QStringView(&rhs, 1); }
1953inline bool operator> (QStringView lhs, QChar rhs) noexcept { return lhs > QStringView(&rhs, 1); }
1954inline bool operator>=(QStringView lhs, QChar rhs) noexcept { return lhs >= QStringView(&rhs, 1); }
1955
1956inline bool operator==(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) == rhs; }
1957inline bool operator!=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) != rhs; }
1958inline bool operator< (QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) < rhs; }
1959inline bool operator<=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) <= rhs; }
1960inline bool operator> (QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) > rhs; }
1961inline bool operator>=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) >= rhs; }
1962
1963// QStringView <> QLatin1String
1964inline bool operator==(QStringView lhs, QLatin1String rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
1965inline bool operator!=(QStringView lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
1966inline bool operator< (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
1967inline bool operator<=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
1968inline bool operator> (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
1969inline bool operator>=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
1970
1971inline bool operator==(QLatin1String lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
1972inline bool operator!=(QLatin1String lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
1973inline bool operator< (QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
1974inline bool operator<=(QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
1975inline bool operator> (QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
1976inline bool operator>=(QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
1977
1978#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1979// QStringRef <> QByteArray
1980inline QT_ASCII_CAST_WARN bool operator==(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) == 0; }
1981inline QT_ASCII_CAST_WARN bool operator!=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) != 0; }
1982inline QT_ASCII_CAST_WARN bool operator< (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) < 0; }
1983inline QT_ASCII_CAST_WARN bool operator> (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) > 0; }
1984inline QT_ASCII_CAST_WARN bool operator<=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) <= 0; }
1985inline QT_ASCII_CAST_WARN bool operator>=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) >= 0; }
1986
1987inline QT_ASCII_CAST_WARN bool operator==(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) == 0; }
1988inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) != 0; }
1989inline QT_ASCII_CAST_WARN bool operator< (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) > 0; }
1990inline QT_ASCII_CAST_WARN bool operator> (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) < 0; }
1991inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) >= 0; }
1992inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) <= 0; }
1993
1994// QStringRef <> const char *
1995inline QT_ASCII_CAST_WARN bool QStringRef::operator==(const char *s) const
1996{ return QString::compare_helper(constData(), size(), s, -1) == 0; }
1997inline QT_ASCII_CAST_WARN bool QStringRef::operator!=(const char *s) const
1998{ return QString::compare_helper(constData(), size(), s, -1) != 0; }
1999inline QT_ASCII_CAST_WARN bool QStringRef::operator<(const char *s) const
2000{ return QString::compare_helper(constData(), size(), s, -1) < 0; }
2001inline QT_ASCII_CAST_WARN bool QStringRef::operator<=(const char *s) const
2002{ return QString::compare_helper(constData(), size(), s, -1) <= 0; }
2003inline QT_ASCII_CAST_WARN bool QStringRef::operator>(const char *s) const
2004{ return QString::compare_helper(constData(), size(), s, -1) > 0; }
2005inline QT_ASCII_CAST_WARN bool QStringRef::operator>=(const char *s) const
2006{ return QString::compare_helper(constData(), size(), s, -1) >= 0; }
2007
2008inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QStringRef &s2)
2009{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) == 0; }
2010inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QStringRef &s2)
2011{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) != 0; }
2012inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QStringRef &s2)
2013{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) > 0; }
2014inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QStringRef &s2)
2015{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
2016inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QStringRef &s2)
2017{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) < 0; }
2018inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2)
2019{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; }
2020#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
2021
2022inline int QString::localeAwareCompare(const QStringRef &s) const
2023{ return localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
2024inline int QString::localeAwareCompare(const QString& s1, const QStringRef& s2)
2025{ return localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
2026inline int QStringRef::localeAwareCompare(const QString &s) const
2027{ return QString::localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
2028inline int QStringRef::localeAwareCompare(const QStringRef &s) const
2029{ return QString::localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
2030inline int QStringRef::localeAwareCompare(QStringView s) const
2031{ return QString::localeAwareCompare_helper(constData(), length(), s.data(), int(s.size())); }
2032inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QString &s2)
2033{ return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
2034inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef &s2)
2035{ return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
2036inline int QStringRef::localeAwareCompare(QStringView s1, QStringView s2)
2037{ return QString::localeAwareCompare_helper(s1.data(), int(s1.size()), s2.data(), int(s2.size())); }
2038
2039#if QT_STRINGVIEW_LEVEL < 2
2040inline bool QStringRef::contains(const QString &s, Qt::CaseSensitivity cs) const
2041{ return indexOf(s, 0, cs) != -1; }
2042inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
2043{ return indexOf(s, 0, cs) != -1; }
2044#endif
2045inline bool QStringRef::contains(QLatin1String s, Qt::CaseSensitivity cs) const
2046{ return indexOf(s, 0, cs) != -1; }
2047inline bool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const
2048{ return indexOf(c, 0, cs) != -1; }
2049inline bool QStringRef::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
2050{ return indexOf(s, 0, cs) != -1; }
2051
2052inline QString &QString::insert(int i, const QStringRef &s)
2053{ return insert(i, s.constData(), s.length()); }
2054
2055#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
2056inline QString operator+(const QString &s1, const QStringRef &s2)
2057{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2058inline QString operator+(const QStringRef &s1, const QString &s2)
2059{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2060inline QString operator+(const QStringRef &s1, QLatin1String s2)
2061{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2062inline QString operator+(QLatin1String s1, const QStringRef &s2)
2063{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2064inline QString operator+(const QStringRef &s1, const QStringRef &s2)
2065{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2066inline QString operator+(const QStringRef &s1, QChar s2)
2067{ QString t; t.reserve(s1.size() + 1); t += s1; t += s2; return t; }
2068inline QString operator+(QChar s1, const QStringRef &s2)
2069{ QString t; t.reserve(1 + s2.size()); t += s1; t += s2; return t; }
2070#endif // !(QT_USE_FAST_OPERATOR_PLUS || QT_USE_QSTRINGBUILDER)
2071
2072namespace Qt {
2073#if QT_DEPRECATED_SINCE(5, 0)
2074QT_DEPRECATED inline QString escape(const QString &plain) {
2075 return plain.toHtmlEscaped();
2076}
2077#endif
2078}
2079
2080namespace QtPrivate {
2081// used by qPrintable() and qUtf8Printable() macros
2082inline const QString &asString(const QString &s) { return s; }
2083inline QString &&asString(QString &&s) { return std::move(s); }
2084}
2085
2086//
2087// QStringView::arg() implementation
2088//
2089
2090namespace QtPrivate {
2091
2092struct ArgBase {
2093 enum Tag : uchar { L1, U8, U16 } tag;
2094};
2095
2096struct QStringViewArg : ArgBase {
2097 QStringView string;
2098 QStringViewArg() = default;
2099 Q_DECL_CONSTEXPR explicit QStringViewArg(QStringView v) noexcept : ArgBase{U16}, string{v} {}
2100};
2101
2102struct QLatin1StringArg : ArgBase {
2103 QLatin1String string;
2104 QLatin1StringArg() = default;
2105 Q_DECL_CONSTEXPR explicit QLatin1StringArg(QLatin1String v) noexcept : ArgBase{L1}, string{v} {}
2106};
2107
2108Q_REQUIRED_RESULT Q_CORE_EXPORT QString argToQString(QStringView pattern, size_t n, const ArgBase **args);
2109Q_REQUIRED_RESULT Q_CORE_EXPORT QString argToQString(QLatin1String pattern, size_t n, const ArgBase **args);
2110
2111template <typename StringView, typename...Args>
2112Q_REQUIRED_RESULT Q_ALWAYS_INLINE QString argToQStringDispatch(StringView pattern, const Args &...args)
2113{
2114 const ArgBase *argBases[] = {&args..., /* avoid zero-sized array */ nullptr};
2115 return QtPrivate::argToQString(pattern, sizeof...(Args), argBases);
2116}
2117
2118 inline QStringViewArg qStringLikeToArg(const QString &s) noexcept { return QStringViewArg{qToStringViewIgnoringNull(s)}; }
2119Q_DECL_CONSTEXPR inline QStringViewArg qStringLikeToArg(QStringView s) noexcept { return QStringViewArg{s}; }
2120 inline QStringViewArg qStringLikeToArg(const QChar &c) noexcept { return QStringViewArg{QStringView{&c, 1}}; }
2121Q_DECL_CONSTEXPR inline QLatin1StringArg qStringLikeToArg(QLatin1String s) noexcept { return QLatin1StringArg{s}; }
2122
2123} // namespace QtPrivate
2124
2125template <typename...Args>
2126Q_ALWAYS_INLINE
2127QString QStringView::arg(Args &&...args) const
2128{
2129 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
2130}
2131
2132template <typename...Args>
2133Q_ALWAYS_INLINE
2134QString QLatin1String::arg(Args &&...args) const
2135{
2136 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
2137}
2138
2139inline qsizetype QStringView::count(QChar c, Qt::CaseSensitivity cs) const noexcept
2140{ return toString().count(c, cs); }
2141inline qsizetype QStringView::count(QStringView s, Qt::CaseSensitivity cs) const noexcept
2142{ return toString().count(s.toString(), cs); }
2143
2144inline short QStringView::toShort(bool *ok, int base) const
2145{ return toString().toShort(ok, base); }
2146inline ushort QStringView::toUShort(bool *ok, int base) const
2147{ return toString().toUShort(ok, base); }
2148inline int QStringView::toInt(bool *ok, int base) const
2149{ return toString().toInt(ok, base); }
2150inline uint QStringView::toUInt(bool *ok, int base) const
2151{ return toString().toUInt(ok, base); }
2152inline long QStringView::toLong(bool *ok, int base) const
2153{ return toString().toLong(ok, base); }
2154inline ulong QStringView::toULong(bool *ok, int base) const
2155{ return toString().toULong(ok, base); }
2156inline qlonglong QStringView::toLongLong(bool *ok, int base) const
2157{ return toString().toLongLong(ok, base); }
2158inline qulonglong QStringView::toULongLong(bool *ok, int base) const
2159{ return toString().toULongLong(ok, base); }
2160inline float QStringView::toFloat(bool *ok) const
2161{ return toString().toFloat(ok); }
2162inline double QStringView::toDouble(bool *ok) const
2163{ return toString().toDouble(ok); }
2164
2165QT_END_NAMESPACE
2166
2167#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
2168#include <QtCore/qstringbuilder.h>
2169#endif
2170
2171#endif // QSTRING_H
2172