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