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