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