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)
67 Q_FORWARD_DECLARE_CF_TYPE(CFString);
68 Q_FORWARD_DECLARE_OBJC_CLASS(NSString);
69 #endif
70
71 QT_BEGIN_NAMESPACE
72
73 class QCharRef;
74 class QRegExp;
75 class QRegularExpression;
76 class QRegularExpressionMatch;
77 class QString;
78 class QStringList;
79 class QTextCodec;
80 class QStringRef;
81 template <typename T> class QVector;
82
83 namespace QtPrivate {
84 template <bool...B> class BoolList;
85 }
86
87 class QLatin1String
88 {
89 public:
QLatin1String()90 Q_DECL_CONSTEXPR inline QLatin1String() noexcept : m_size(0), m_data(nullptr) {}
QLatin1String(const char * s)91 Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) noexcept : m_size(s ? int(strlen(s)) : 0), m_data(s) {}
QLatin1String(const char * f,const char * l)92 Q_DECL_CONSTEXPR explicit QLatin1String(const char *f, const char *l)
93 : QLatin1String(f, int(l - f)) {}
QLatin1String(const char * s,int sz)94 Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) noexcept : m_size(sz), m_data(s) {}
QLatin1String(const QByteArray & s)95 inline explicit QLatin1String(const QByteArray &s) noexcept : m_size(int(qstrnlen(s.constData(), s.size()))), m_data(s.constData()) {}
96
latin1()97 Q_DECL_CONSTEXPR const char *latin1() const noexcept { return m_data; }
size()98 Q_DECL_CONSTEXPR int size() const noexcept { return m_size; }
data()99 Q_DECL_CONSTEXPR const char *data() const noexcept { return m_data; }
100
isNull()101 Q_DECL_CONSTEXPR bool isNull() const noexcept { return !data(); }
isEmpty()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
at(int i)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
front()111 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QLatin1Char front() const { return at(0); }
back()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); }
compare(QChar c)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() ; }
compare(QChar c,Qt::CaseSensitivity cs)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); }
startsWith(QChar c)127 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR bool startsWith(QChar c) const noexcept
128 { return !isEmpty() && front() == c; }
startsWith(QChar c,Qt::CaseSensitivity cs)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); }
endsWith(QChar c)136 Q_REQUIRED_RESULT Q_DECL_CONSTEXPR bool endsWith(QChar c) const noexcept
137 { return !isEmpty() && back() == c; }
endsWith(QChar c,Qt::CaseSensitivity cs)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
begin()170 Q_DECL_CONSTEXPR const_iterator begin() const noexcept { return data(); }
cbegin()171 Q_DECL_CONSTEXPR const_iterator cbegin() const noexcept { return data(); }
end()172 Q_DECL_CONSTEXPR const_iterator end() const noexcept { return data() + size(); }
cend()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
rbegin()178 const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
crbegin()179 const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
rend()180 const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
crend()181 const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
182
mid(int pos)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); }
mid(int pos,int n)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); }
left(int n)187 Q_DECL_CONSTEXPR QLatin1String left(int n) const
188 { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QLatin1String(m_data, n); }
right(int 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); }
chopped(int 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
chop(int n)194 Q_DECL_RELAXED_CONSTEXPR void chop(int n)
195 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size -= n; }
truncate(int n)196 Q_DECL_RELAXED_CONSTEXPR void truncate(int n)
197 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); m_size = n; }
198
trimmed()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
224 private:
225 int m_size;
226 const char *m_data;
227 };
228 Q_DECLARE_TYPEINFO(QLatin1String, Q_MOVABLE_TYPE);
229
230 // Qt 4.x compatibility
231 #if QT_DEPRECATED_SINCE(5, 14)
232 QT_DEPRECATED_X("Use QLatin1String")
233 typedef QLatin1String QLatin1Literal;
234 #endif
235
236 //
237 // QLatin1String inline implementations
238 //
isLatin1(QLatin1String)239 Q_DECL_CONSTEXPR bool QtPrivate::isLatin1(QLatin1String) noexcept
240 { return true; }
241
242 //
243 // QStringView members that require QLatin1String:
244 //
compare(QLatin1String s,Qt::CaseSensitivity cs)245 int QStringView::compare(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
246 { return QtPrivate::compareStrings(*this, s, cs); }
startsWith(QLatin1String s,Qt::CaseSensitivity cs)247 bool QStringView::startsWith(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
248 { return QtPrivate::startsWith(*this, s, cs); }
endsWith(QLatin1String s,Qt::CaseSensitivity cs)249 bool QStringView::endsWith(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
250 { return QtPrivate::endsWith(*this, s, cs); }
indexOf(QLatin1String s,qsizetype from,Qt::CaseSensitivity cs)251 qsizetype QStringView::indexOf(QLatin1String s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
252 { return QtPrivate::findString(*this, from, s, cs); }
contains(QLatin1String s,Qt::CaseSensitivity cs)253 bool QStringView::contains(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
254 { return indexOf(s, 0, cs) != qsizetype(-1); }
lastIndexOf(QLatin1String s,qsizetype from,Qt::CaseSensitivity cs)255 qsizetype QStringView::lastIndexOf(QLatin1String s, qsizetype from, Qt::CaseSensitivity cs) const noexcept
256 { return QtPrivate::lastIndexOf(*this, from, s, cs); }
257
258 class Q_CORE_EXPORT QString
259 {
260 public:
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);
QString(QString && other)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; }
swap(QString & other)276 inline void swap(QString &other) noexcept { qSwap(d, other.d); }
size()277 inline int size() const { return d->size; }
count()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;
isSharedWith(const QString & other)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
front()308 Q_REQUIRED_RESULT inline QChar front() const { return at(0); }
309 Q_REQUIRED_RESULT inline QCharRef front();
back()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
362 private:
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> {};
372 public:
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
arg(Args &&...args)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;
contains(const QRegExp & rx)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;
contains(QRegExp & rx)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 ®, 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;
chopped(int n)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
toLower()508 Q_REQUIRED_RESULT QString toLower() const &
509 { return toLower_helper(*this); }
toLower()510 Q_REQUIRED_RESULT QString toLower() &&
511 { return toLower_helper(*this); }
toUpper()512 Q_REQUIRED_RESULT QString toUpper() const &
513 { return toUpper_helper(*this); }
toUpper()514 Q_REQUIRED_RESULT QString toUpper() &&
515 { return toUpper_helper(*this); }
toCaseFolded()516 Q_REQUIRED_RESULT QString toCaseFolded() const &
517 { return toCaseFolded_helper(*this); }
toCaseFolded()518 Q_REQUIRED_RESULT QString toCaseFolded() &&
519 { return toCaseFolded_helper(*this); }
trimmed()520 Q_REQUIRED_RESULT QString trimmed() const &
521 { return trimmed_helper(*this); }
trimmed()522 Q_REQUIRED_RESULT QString trimmed() &&
523 { return trimmed_helper(*this); }
simplified()524 Q_REQUIRED_RESULT QString simplified() const &
525 { return simplified_helper(*this); }
simplified()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);
insert(int i,const QString & s)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);
insert(int i,QStringView 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);
append(QStringView s)552 inline QString &append(QStringView s) { return append(s.data(), s.length()); }
prepend(QChar c)553 inline QString &prepend(QChar c) { return insert(0, c); }
prepend(const QChar * uc,int len)554 inline QString &prepend(const QChar *uc, int len) { return insert(0, uc, len); }
prepend(const QString & s)555 inline QString &prepend(const QString &s) { return insert(0, s); }
prepend(const QStringRef & s)556 inline QString &prepend(const QStringRef &s) { return insert(0, s); }
prepend(QLatin1String s)557 inline QString &prepend(QLatin1String s) { return insert(0, s); }
prepend(QStringView 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);
remove(const QRegExp & rx)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);
remove(const QRegularExpression & re)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
634 public:
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)
toLatin1()679 Q_REQUIRED_RESULT QByteArray toLatin1() const &
680 { return toLatin1_helper(*this); }
toLatin1()681 Q_REQUIRED_RESULT QByteArray toLatin1() &&
682 { return toLatin1_helper_inplace(*this); }
toUtf8()683 Q_REQUIRED_RESULT QByteArray toUtf8() const &
684 { return toUtf8_helper(*this); }
toUtf8()685 Q_REQUIRED_RESULT QByteArray toUtf8() &&
686 { return toUtf8_helper(*this); }
toLocal8Bit()687 Q_REQUIRED_RESULT QByteArray toLocal8Bit() const &
688 { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); }
toLocal8Bit()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 }
fromLatin1(const QByteArray & str)712 static inline QString fromLatin1(const QByteArray &str)
713 { return str.isNull() ? QString() : fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); }
fromUtf8(const QByteArray & str)714 static inline QString fromUtf8(const QByteArray &str)
715 { return str.isNull() ? QString() : fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); }
fromLocal8Bit(const QByteArray & str)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); }
fromAscii(const QByteArray & str)732 QT_DEPRECATED static inline QString fromAscii(const QByteArray &str)
733 { return fromLatin1(str); }
toAscii()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;
localeAwareCompare(const QString & s1,const QString & s2)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>
QString(const char (& ch)[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)
QString(const char * ch)835 inline QT_ASCII_CAST_WARN QString(const char *ch)
836 : d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1))
837 {}
QString(const QByteArray & a)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
prepend(const char * s)849 inline QT_ASCII_CAST_WARN QString &prepend(const char *s)
850 { return prepend(QString::fromUtf8(s)); }
prepend(const QByteArray & s)851 inline QT_ASCII_CAST_WARN QString &prepend(const QByteArray &s)
852 { return prepend(QString::fromUtf8(s)); }
append(const char * s)853 inline QT_ASCII_CAST_WARN QString &append(const char *s)
854 { return append(QString::fromUtf8(s)); }
append(const QByteArray & s)855 inline QT_ASCII_CAST_WARN QString &append(const QByteArray &s)
856 { return append(QString::fromUtf8(s)); }
insert(int i,const char * s)857 inline QT_ASCII_CAST_WARN QString &insert(int i, const char *s)
858 { return insert(i, QString::fromUtf8(s)); }
insert(int i,const QByteArray & 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;
rbegin()911 reverse_iterator rbegin() { return reverse_iterator(end()); }
rend()912 reverse_iterator rend() { return reverse_iterator(begin()); }
rbegin()913 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
rend()914 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
crbegin()915 const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
crend()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;
push_back(QChar c)926 inline void push_back(QChar c) { append(c); }
push_back(const QString & s)927 inline void push_back(const QString &s) { append(s); }
push_front(QChar c)928 inline void push_front(QChar c) { prepend(c); }
push_front(const QString & s)929 inline void push_front(const QString &s) { prepend(s); }
shrink_to_fit()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;
QString(const Null &)955 inline QString(const Null &): d(Data::sharedNull()) {}
956 inline QString &operator=(const Null &) { *this = QString(); return *this; }
957 #endif
isNull()958 inline bool isNull() const { return d == Data::sharedNull(); }
959
960
961 bool isSimpleText() const;
962 bool isRightToLeft() const;
isValidUtf16()963 Q_REQUIRED_RESULT bool isValidUtf16() const noexcept
964 { return QStringView(*this).isValidUtf16(); }
965
966 QString(int size, Qt::Initialization);
QString(QStringDataPtr dd)967 Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {}
968
969 private:
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
toIntegral_helper(const QChar * data,int len,bool * ok,int base)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
1053 public:
1054 typedef Data * DataPtr;
data_ptr()1055 inline DataPtr &data_ptr() { return d; }
1056 };
1057
1058 //
1059 // QStringView inline members that require QString:
1060 //
toString()1061 QString QStringView::toString() const
1062 { return Q_ASSERT(size() == length()), QString(data(), length()); }
1063
1064 //
1065 // QString inline members
1066 //
QString(QLatin1String aLatin1)1067 inline QString::QString(QLatin1String aLatin1) : d(fromLatin1_helper(aLatin1.latin1(), aLatin1.size()))
1068 { }
length()1069 inline int QString::length() const
1070 { return d->size; }
at(int i)1071 inline const QChar QString::at(int i) const
1072 { Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); }
1073 inline const QChar QString::operator[](int i) const
1074 { Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); }
1075 inline const QChar QString::operator[](uint i) const
1076 { Q_ASSERT(i < uint(size())); return QChar(d->data()[i]); }
isEmpty()1077 inline bool QString::isEmpty() const
1078 { return d->size == 0; }
unicode()1079 inline const QChar *QString::unicode() const
1080 { return reinterpret_cast<const QChar*>(d->data()); }
data()1081 inline const QChar *QString::data() const
1082 { return reinterpret_cast<const QChar*>(d->data()); }
data()1083 inline QChar *QString::data()
1084 { detach(); return reinterpret_cast<QChar*>(d->data()); }
constData()1085 inline const QChar *QString::constData() const
1086 { return reinterpret_cast<const QChar*>(d->data()); }
detach()1087 inline void QString::detach()
1088 { if (d->ref.isShared() || (d->offset != sizeof(QStringData))) reallocData(uint(d->size) + 1u); }
isDetached()1089 inline bool QString::isDetached() const
1090 { return !d->ref.isShared(); }
clear()1091 inline void QString::clear()
1092 { if (!isNull()) *this = QString(); }
QString(const QString & other)1093 inline QString::QString(const QString &other) noexcept : d(other.d)
1094 { Q_ASSERT(&other != this); d->ref.ref(); }
capacity()1095 inline int QString::capacity() const
1096 { return d->alloc ? d->alloc - 1 : 0; }
setNum(short n,int base)1097 inline QString &QString::setNum(short n, int base)
1098 { return setNum(qlonglong(n), base); }
setNum(ushort n,int base)1099 inline QString &QString::setNum(ushort n, int base)
1100 { return setNum(qulonglong(n), base); }
setNum(int n,int base)1101 inline QString &QString::setNum(int n, int base)
1102 { return setNum(qlonglong(n), base); }
setNum(uint n,int base)1103 inline QString &QString::setNum(uint n, int base)
1104 { return setNum(qulonglong(n), base); }
setNum(long n,int base)1105 inline QString &QString::setNum(long n, int base)
1106 { return setNum(qlonglong(n), base); }
setNum(ulong n,int base)1107 inline QString &QString::setNum(ulong n, int base)
1108 { return setNum(qulonglong(n), base); }
setNum(float n,char f,int prec)1109 inline QString &QString::setNum(float n, char f, int prec)
1110 { return setNum(double(n),f,prec); }
arg(int a,int fieldWidth,int base,QChar fillChar)1111 inline QString QString::arg(int a, int fieldWidth, int base, QChar fillChar) const
1112 { return arg(qlonglong(a), fieldWidth, base, fillChar); }
arg(uint a,int fieldWidth,int base,QChar fillChar)1113 inline QString QString::arg(uint a, int fieldWidth, int base, QChar fillChar) const
1114 { return arg(qulonglong(a), fieldWidth, base, fillChar); }
arg(long a,int fieldWidth,int base,QChar fillChar)1115 inline QString QString::arg(long a, int fieldWidth, int base, QChar fillChar) const
1116 { return arg(qlonglong(a), fieldWidth, base, fillChar); }
arg(ulong a,int fieldWidth,int base,QChar fillChar)1117 inline QString QString::arg(ulong a, int fieldWidth, int base, QChar fillChar) const
1118 { return arg(qulonglong(a), fieldWidth, base, fillChar); }
arg(short a,int fieldWidth,int base,QChar fillChar)1119 inline QString QString::arg(short a, int fieldWidth, int base, QChar fillChar) const
1120 { return arg(qlonglong(a), fieldWidth, base, fillChar); }
arg(ushort a,int fieldWidth,int base,QChar fillChar)1121 inline 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
arg(const QString & a1,const QString & a2)1124 inline QString QString::arg(const QString &a1, const QString &a2) const
1125 { return qToStringViewIgnoringNull(*this).arg(a1, a2); }
arg(const QString & a1,const QString & a2,const QString & a3)1126 inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3) const
1127 { return qToStringViewIgnoringNull(*this).arg(a1, a2, a3); }
arg(const QString & a1,const QString & a2,const QString & a3,const QString & a4)1128 inline 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); }
arg(const QString & a1,const QString & a2,const QString & a3,const QString & a4,const QString & a5)1131 inline 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); }
arg(const QString & a1,const QString & a2,const QString & a3,const QString & a4,const QString & a5,const QString & a6)1134 inline 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); }
arg(const QString & a1,const QString & a2,const QString & a3,const QString & a4,const QString & a5,const QString & a6,const QString & a7)1137 inline 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); }
arg(const QString & a1,const QString & a2,const QString & a3,const QString & a4,const QString & a5,const QString & a6,const QString & a7,const QString & a8)1141 inline 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); }
arg(const QString & a1,const QString & a2,const QString & a3,const QString & a4,const QString & a5,const QString & a6,const QString & a7,const QString & a8,const QString & a9)1145 inline 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
section(QChar asep,int astart,int aend,SectionFlags aflags)1151 inline QString QString::section(QChar asep, int astart, int aend, SectionFlags aflags) const
1152 { return section(QString(asep), astart, aend, aflags); }
1153
1154 QT_WARNING_PUSH
1155 QT_WARNING_DISABLE_MSVC(4127) // "conditional expression is constant"
1156 QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable"
1157
toWCharArray(wchar_t * array)1158 inline int QString::toWCharArray(wchar_t *array) const
1159 {
1160 return qToStringViewIgnoringNull(*this).toWCharArray(array);
1161 }
1162
toWCharArray(wchar_t * array)1163 int 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
1175 QT_WARNING_POP
1176
fromWCharArray(const wchar_t * string,int size)1177 inline 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
1183 class
1184 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1185 Q_CORE_EXPORT
1186 #endif
1187 QCharRef { // ### Qt 7: remove
1188 QString &s;
1189 int i;
QCharRef(QString & str,int idx)1190 inline QCharRef(QString &str, int idx)
1191 : s(str),i(idx) {}
1192 friend class QString;
1193 public:
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.
QChar()1199 inline operator QChar() const
1200 {
1201 using namespace QtPrivate::DeprecatedRefClassBehavior;
1202 if (Q_LIKELY(i < s.d->size))
1203 return QChar(s.d->data()[i]);
1204 #ifdef QT_DEBUG
1205 warn(WarningType::OutOfRange, EmittingClass::QCharRef);
1206 #endif
1207 return QChar();
1208 }
1209 inline QCharRef &operator=(QChar c)
1210 {
1211 using namespace QtPrivate::DeprecatedRefClassBehavior;
1212 if (Q_UNLIKELY(i >= s.d->size)) {
1213 #ifdef QT_DEBUG
1214 warn(WarningType::OutOfRange, EmittingClass::QCharRef);
1215 #endif
1216 s.resize(i + 1, QLatin1Char(' '));
1217 } else {
1218 #ifdef QT_DEBUG
1219 if (Q_UNLIKELY(!s.isDetached()))
1220 warn(WarningType::DelayedDetach, EmittingClass::QCharRef);
1221 #endif
1222 s.detach();
1223 }
1224 s.d->data()[i] = c.unicode();
1225 return *this;
1226 }
1227
1228 // An operator= for each QChar cast constructors
1229 #ifndef QT_NO_CAST_FROM_ASCII
1230 inline QT_ASCII_CAST_WARN QCharRef &operator=(char c)
1231 { return operator=(QChar::fromLatin1(c)); }
1232 inline QT_ASCII_CAST_WARN QCharRef &operator=(uchar c)
1233 { return operator=(QChar::fromLatin1(c)); }
1234 #else
1235 // prevent char -> int promotion, bypassing QT_NO_CAST_FROM_ASCII
1236 QCharRef &operator=(char c) = delete;
1237 QCharRef &operator=(uchar c) = delete;
1238 #endif
1239 inline QCharRef &operator=(const QCharRef &c) { return operator=(QChar(c)); }
1240 inline QCharRef &operator=(ushort rc) { return operator=(QChar(rc)); }
1241 inline QCharRef &operator=(short rc) { return operator=(QChar(rc)); }
1242 inline QCharRef &operator=(uint rc) { return operator=(QChar(rc)); }
1243 inline QCharRef &operator=(int rc) { return operator=(QChar(rc)); }
1244
1245 // each function...
isNull()1246 inline bool isNull() const { return QChar(*this).isNull(); }
isPrint()1247 inline bool isPrint() const { return QChar(*this).isPrint(); }
isPunct()1248 inline bool isPunct() const { return QChar(*this).isPunct(); }
isSpace()1249 inline bool isSpace() const { return QChar(*this).isSpace(); }
isMark()1250 inline bool isMark() const { return QChar(*this).isMark(); }
isLetter()1251 inline bool isLetter() const { return QChar(*this).isLetter(); }
isNumber()1252 inline bool isNumber() const { return QChar(*this).isNumber(); }
isLetterOrNumber()1253 inline bool isLetterOrNumber() { return QChar(*this).isLetterOrNumber(); }
isDigit()1254 inline bool isDigit() const { return QChar(*this).isDigit(); }
isLower()1255 inline bool isLower() const { return QChar(*this).isLower(); }
isUpper()1256 inline bool isUpper() const { return QChar(*this).isUpper(); }
isTitleCase()1257 inline bool isTitleCase() const { return QChar(*this).isTitleCase(); }
1258
digitValue()1259 inline int digitValue() const { return QChar(*this).digitValue(); }
toLower()1260 QChar toLower() const { return QChar(*this).toLower(); }
toUpper()1261 QChar toUpper() const { return QChar(*this).toUpper(); }
toTitleCase()1262 QChar toTitleCase () const { return QChar(*this).toTitleCase(); }
1263
category()1264 QChar::Category category() const { return QChar(*this).category(); }
direction()1265 QChar::Direction direction() const { return QChar(*this).direction(); }
joiningType()1266 QChar::JoiningType joiningType() const { return QChar(*this).joiningType(); }
1267 #if QT_DEPRECATED_SINCE(5, 3)
joining()1268 QT_DEPRECATED QChar::Joining joining() const
1269 {
1270 switch (QChar(*this).joiningType()) {
1271 case QChar::Joining_Causing: return QChar::Center;
1272 case QChar::Joining_Dual: return QChar::Dual;
1273 case QChar::Joining_Right: return QChar::Right;
1274 case QChar::Joining_None:
1275 case QChar::Joining_Left:
1276 case QChar::Joining_Transparent:
1277 default: return QChar::OtherJoining;
1278 }
1279 }
1280 #endif
hasMirrored()1281 bool hasMirrored() const { return QChar(*this).hasMirrored(); }
mirroredChar()1282 QChar mirroredChar() const { return QChar(*this).mirroredChar(); }
decomposition()1283 QString decomposition() const { return QChar(*this).decomposition(); }
decompositionTag()1284 QChar::Decomposition decompositionTag() const { return QChar(*this).decompositionTag(); }
combiningClass()1285 uchar combiningClass() const { return QChar(*this).combiningClass(); }
1286
script()1287 inline QChar::Script script() const { return QChar(*this).script(); }
1288
unicodeVersion()1289 QChar::UnicodeVersion unicodeVersion() const { return QChar(*this).unicodeVersion(); }
1290
cell()1291 inline uchar cell() const { return QChar(*this).cell(); }
row()1292 inline uchar row() const { return QChar(*this).row(); }
1293 inline void setCell(uchar cell);
1294 inline void setRow(uchar row);
1295
1296 #if QT_DEPRECATED_SINCE(5, 0)
toAscii()1297 QT_DEPRECATED char toAscii() const { return QChar(*this).toLatin1(); }
1298 #endif
toLatin1()1299 char toLatin1() const { return QChar(*this).toLatin1(); }
unicode()1300 ushort unicode() const { return QChar(*this).unicode(); }
unicode()1301 ushort& unicode() { return s.data()[i].unicode(); }
1302
1303 };
1304 Q_DECLARE_TYPEINFO(QCharRef, Q_MOVABLE_TYPE);
1305
setRow(uchar arow)1306 inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
setCell(uchar acell)1307 inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
1308
1309
QString()1310 inline QString::QString() noexcept : d(Data::sharedNull()) {}
~QString()1311 inline QString::~QString() { if (!d->ref.deref()) Data::deallocate(d); }
1312
reserve(int asize)1313 inline void QString::reserve(int asize)
1314 {
1315 if (d->ref.isShared() || uint(asize) >= d->alloc)
1316 reallocData(qMax(asize, d->size) + 1u);
1317
1318 if (!d->capacityReserved) {
1319 // cannot set unconditionally, since d could be the shared_null/shared_empty (which is const)
1320 d->capacityReserved = true;
1321 }
1322 }
1323
squeeze()1324 inline void QString::squeeze()
1325 {
1326 if (d->ref.isShared() || uint(d->size) + 1u < d->alloc)
1327 reallocData(uint(d->size) + 1u);
1328
1329 if (d->capacityReserved) {
1330 // cannot set unconditionally, since d could be shared_null or
1331 // otherwise static.
1332 d->capacityReserved = false;
1333 }
1334 }
1335
setUtf16(const ushort * autf16,int asize)1336 inline QString &QString::setUtf16(const ushort *autf16, int asize)
1337 { return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
1338 inline QCharRef QString::operator[](int i)
1339 { Q_ASSERT(i >= 0); detach(); return QCharRef(*this, i); }
1340 inline QCharRef QString::operator[](uint i)
1341 { detach(); return QCharRef(*this, i); }
front()1342 inline QCharRef QString::front() { return operator[](0); }
back()1343 inline QCharRef QString::back() { return operator[](size() - 1); }
begin()1344 inline QString::iterator QString::begin()
1345 { detach(); return reinterpret_cast<QChar*>(d->data()); }
begin()1346 inline QString::const_iterator QString::begin() const
1347 { return reinterpret_cast<const QChar*>(d->data()); }
cbegin()1348 inline QString::const_iterator QString::cbegin() const
1349 { return reinterpret_cast<const QChar*>(d->data()); }
constBegin()1350 inline QString::const_iterator QString::constBegin() const
1351 { return reinterpret_cast<const QChar*>(d->data()); }
end()1352 inline QString::iterator QString::end()
1353 { detach(); return reinterpret_cast<QChar*>(d->data() + d->size); }
end()1354 inline QString::const_iterator QString::end() const
1355 { return reinterpret_cast<const QChar*>(d->data() + d->size); }
cend()1356 inline QString::const_iterator QString::cend() const
1357 { return reinterpret_cast<const QChar*>(d->data() + d->size); }
constEnd()1358 inline QString::const_iterator QString::constEnd() const
1359 { return reinterpret_cast<const QChar*>(d->data() + d->size); }
1360 #if QT_STRINGVIEW_LEVEL < 2
contains(const QString & s,Qt::CaseSensitivity cs)1361 inline bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
1362 { return indexOf(s, 0, cs) != -1; }
contains(const QStringRef & s,Qt::CaseSensitivity cs)1363 inline bool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
1364 { return indexOf(s, 0, cs) != -1; }
1365 #endif
contains(QLatin1String s,Qt::CaseSensitivity cs)1366 inline bool QString::contains(QLatin1String s, Qt::CaseSensitivity cs) const
1367 { return indexOf(s, 0, cs) != -1; }
contains(QChar c,Qt::CaseSensitivity cs)1368 inline bool QString::contains(QChar c, Qt::CaseSensitivity cs) const
1369 { return indexOf(c, 0, cs) != -1; }
contains(QStringView s,Qt::CaseSensitivity cs)1370 inline bool QString::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
1371 { return indexOf(s, 0, cs) != -1; }
1372
1373 #if QT_DEPRECATED_SINCE(5, 9)
1374 inline bool operator==(QString::Null, QString::Null) { return true; }
1375 QT_DEPRECATED_X("use QString::isNull()")
1376 inline bool operator==(QString::Null, const QString &s) { return s.isNull(); }
1377 QT_DEPRECATED_X("use QString::isNull()")
1378 inline bool operator==(const QString &s, QString::Null) { return s.isNull(); }
1379 inline bool operator!=(QString::Null, QString::Null) { return false; }
1380 QT_DEPRECATED_X("use !QString::isNull()")
1381 inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); }
1382 QT_DEPRECATED_X("use !QString::isNull()")
1383 inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); }
1384 #endif
1385
1386 inline bool operator==(QLatin1String s1, QLatin1String s2) noexcept
1387 { return s1.size() == s2.size() && (!s1.size() || !memcmp(s1.latin1(), s2.latin1(), s1.size())); }
1388 inline bool operator!=(QLatin1String s1, QLatin1String s2) noexcept
1389 { return !operator==(s1, s2); }
1390 inline bool operator<(QLatin1String s1, QLatin1String s2) noexcept
1391 {
1392 const int len = qMin(s1.size(), s2.size());
1393 const int r = len ? memcmp(s1.latin1(), s2.latin1(), len) : 0;
1394 return r < 0 || (r == 0 && s1.size() < s2.size());
1395 }
1396 inline bool operator>(QLatin1String s1, QLatin1String s2) noexcept
1397 { return operator<(s2, s1); }
1398 inline bool operator<=(QLatin1String s1, QLatin1String s2) noexcept
1399 { return !operator>(s1, s2); }
1400 inline bool operator>=(QLatin1String s1, QLatin1String s2) noexcept
1401 { return !operator<(s1, s2); }
1402
1403 inline bool QLatin1String::operator==(const QString &s) const noexcept
1404 { return s == *this; }
1405 inline bool QLatin1String::operator!=(const QString &s) const noexcept
1406 { return s != *this; }
1407 inline bool QLatin1String::operator>(const QString &s) const noexcept
1408 { return s < *this; }
1409 inline bool QLatin1String::operator<(const QString &s) const noexcept
1410 { return s > *this; }
1411 inline bool QLatin1String::operator>=(const QString &s) const noexcept
1412 { return s <= *this; }
1413 inline bool QLatin1String::operator<=(const QString &s) const noexcept
1414 { return s >= *this; }
1415
1416 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1417 inline bool QString::operator==(const char *s) const
1418 { return QString::compare_helper(constData(), size(), s, -1) == 0; }
1419 inline bool QString::operator!=(const char *s) const
1420 { return QString::compare_helper(constData(), size(), s, -1) != 0; }
1421 inline bool QString::operator<(const char *s) const
1422 { return QString::compare_helper(constData(), size(), s, -1) < 0; }
1423 inline bool QString::operator>(const char *s) const
1424 { return QString::compare_helper(constData(), size(), s, -1) > 0; }
1425 inline bool QString::operator<=(const char *s) const
1426 { return QString::compare_helper(constData(), size(), s, -1) <= 0; }
1427 inline bool QString::operator>=(const char *s) const
1428 { return QString::compare_helper(constData(), size(), s, -1) >= 0; }
1429
1430 inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QString &s2)
1431 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) == 0; }
1432 inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QString &s2)
1433 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) != 0; }
1434 inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QString &s2)
1435 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) > 0; }
1436 inline 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 inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QString &s2)
1439 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
1440 inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QString &s2)
1441 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; }
1442
1443 inline QT_ASCII_CAST_WARN bool operator==(const char *s1, QLatin1String s2)
1444 { return QString::fromUtf8(s1) == s2; }
1445 inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, QLatin1String s2)
1446 { return QString::fromUtf8(s1) != s2; }
1447 inline QT_ASCII_CAST_WARN bool operator<(const char *s1, QLatin1String s2)
1448 { return (QString::fromUtf8(s1) < s2); }
1449 inline QT_ASCII_CAST_WARN bool operator>(const char *s1, QLatin1String s2)
1450 { return (QString::fromUtf8(s1) > s2); }
1451 inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, QLatin1String s2)
1452 { return (QString::fromUtf8(s1) <= s2); }
1453 inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, QLatin1String s2)
1454 { return (QString::fromUtf8(s1) >= s2); }
1455
1456 inline QT_ASCII_CAST_WARN bool QLatin1String::operator==(const char *s) const
1457 { return QString::fromUtf8(s) == *this; }
1458 inline QT_ASCII_CAST_WARN bool QLatin1String::operator!=(const char *s) const
1459 { return QString::fromUtf8(s) != *this; }
1460 inline QT_ASCII_CAST_WARN bool QLatin1String::operator<(const char *s) const
1461 { return QString::fromUtf8(s) > *this; }
1462 inline QT_ASCII_CAST_WARN bool QLatin1String::operator>(const char *s) const
1463 { return QString::fromUtf8(s) < *this; }
1464 inline QT_ASCII_CAST_WARN bool QLatin1String::operator<=(const char *s) const
1465 { return QString::fromUtf8(s) >= *this; }
1466 inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const char *s) const
1467 { return QString::fromUtf8(s) <= *this; }
1468
1469 inline QT_ASCII_CAST_WARN bool QLatin1String::operator==(const QByteArray &s) const
1470 { return QString::fromUtf8(s) == *this; }
1471 inline QT_ASCII_CAST_WARN bool QLatin1String::operator!=(const QByteArray &s) const
1472 { return QString::fromUtf8(s) != *this; }
1473 inline QT_ASCII_CAST_WARN bool QLatin1String::operator<(const QByteArray &s) const
1474 { return QString::fromUtf8(s) > *this; }
1475 inline QT_ASCII_CAST_WARN bool QLatin1String::operator>(const QByteArray &s) const
1476 { return QString::fromUtf8(s) < *this; }
1477 inline QT_ASCII_CAST_WARN bool QLatin1String::operator<=(const QByteArray &s) const
1478 { return QString::fromUtf8(s) >= *this; }
1479 inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const QByteArray &s) const
1480 { return QString::fromUtf8(s) <= *this; }
1481
1482 inline QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const
1483 { return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) == 0; }
1484 inline QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const
1485 { return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) != 0; }
1486 inline QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const
1487 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; }
1488 inline QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const
1489 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) > 0; }
1490 inline QT_ASCII_CAST_WARN bool QString::operator<=(const QByteArray &s) const
1491 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) <= 0; }
1492 inline QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const
1493 { return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; }
1494
1495 inline bool QByteArray::operator==(const QString &s) const
1496 { return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) == 0; }
1497 inline bool QByteArray::operator!=(const QString &s) const
1498 { return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) != 0; }
1499 inline bool QByteArray::operator<(const QString &s) const
1500 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; }
1501 inline bool QByteArray::operator>(const QString &s) const
1502 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) < 0; }
1503 inline bool QByteArray::operator<=(const QString &s) const
1504 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) >= 0; }
1505 inline bool QByteArray::operator>=(const QString &s) const
1506 { return QString::compare_helper(s.constData(), s.size(), constData(), size()) <= 0; }
1507
1508 #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1509
1510 #if !defined(QT_NO_CAST_TO_ASCII) && QT_DEPRECATED_SINCE(5, 15)
append(const QString & s)1511 inline QByteArray &QByteArray::append(const QString &s)
1512 { return append(s.toUtf8()); }
insert(int i,const QString & s)1513 inline QByteArray &QByteArray::insert(int i, const QString &s)
1514 { return insert(i, s.toUtf8()); }
replace(char c,const QString & after)1515 inline QByteArray &QByteArray::replace(char c, const QString &after)
1516 { return replace(c, after.toUtf8()); }
replace(const QString & before,const char * after)1517 inline QByteArray &QByteArray::replace(const QString &before, const char *after)
1518 { return replace(before.toUtf8(), after); }
replace(const QString & before,const QByteArray & after)1519 inline QByteArray &QByteArray::replace(const QString &before, const QByteArray &after)
1520 { return replace(before.toUtf8(), after); }
1521 inline QByteArray &QByteArray::operator+=(const QString &s)
1522 { return operator+=(s.toUtf8()); }
indexOf(const QString & s,int from)1523 inline int QByteArray::indexOf(const QString &s, int from) const
1524 { return indexOf(s.toUtf8(), from); }
lastIndexOf(const QString & s,int from)1525 inline int QByteArray::lastIndexOf(const QString &s, int from) const
1526 { return lastIndexOf(s.toUtf8(), from); }
1527 #endif // !defined(QT_NO_CAST_TO_ASCII) && QT_DEPRECATED_SINCE(5, 15)
1528
1529 #if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
1530 inline const QString operator+(const QString &s1, const QString &s2)
1531 { QString t(s1); t += s2; return t; }
1532 inline const QString operator+(const QString &s1, QChar s2)
1533 { QString t(s1); t += s2; return t; }
1534 inline const QString operator+(QChar s1, const QString &s2)
1535 { QString t(s1); t += s2; return t; }
1536 # if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1537 inline QT_ASCII_CAST_WARN const QString operator+(const QString &s1, const char *s2)
1538 { QString t(s1); t += QString::fromUtf8(s2); return t; }
1539 inline QT_ASCII_CAST_WARN const QString operator+(const char *s1, const QString &s2)
1540 { QString t = QString::fromUtf8(s1); t += s2; return t; }
1541 inline QT_ASCII_CAST_WARN const QString operator+(char c, const QString &s)
1542 { QString t = s; t.prepend(QChar::fromLatin1(c)); return t; }
1543 inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, char c)
1544 { QString t = s; t += QChar::fromLatin1(c); return t; }
1545 inline QT_ASCII_CAST_WARN const QString operator+(const QByteArray &ba, const QString &s)
1546 { QString t = QString::fromUtf8(ba); t += s; return t; }
1547 inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, const QByteArray &ba)
1548 { QString t(s); t += QString::fromUtf8(ba); return t; }
1549 # endif // QT_NO_CAST_FROM_ASCII
1550 #endif // QT_USE_QSTRINGBUILDER
1551
toStdString()1552 inline std::string QString::toStdString() const
1553 { return toUtf8().toStdString(); }
1554
fromStdString(const std::string & s)1555 inline QString QString::fromStdString(const std::string &s)
1556 { return fromUtf8(s.data(), int(s.size())); }
1557
toStdWString()1558 inline std::wstring QString::toStdWString() const
1559 {
1560 std::wstring str;
1561 str.resize(length());
1562 #if __cplusplus >= 201703L
1563 str.resize(toWCharArray(str.data()));
1564 #else
1565 if (length())
1566 str.resize(toWCharArray(&str.front()));
1567 #endif
1568 return str;
1569 }
1570
fromStdWString(const std::wstring & s)1571 inline QString QString::fromStdWString(const std::wstring &s)
1572 { return fromWCharArray(s.data(), int(s.size())); }
1573
1574 #if defined(Q_STDLIB_UNICODE_STRINGS)
fromStdU16String(const std::u16string & s)1575 inline QString QString::fromStdU16String(const std::u16string &s)
1576 { return fromUtf16(s.data(), int(s.size())); }
1577
toStdU16String()1578 inline std::u16string QString::toStdU16String() const
1579 { return std::u16string(reinterpret_cast<const char16_t*>(utf16()), length()); }
1580
fromStdU32String(const std::u32string & s)1581 inline QString QString::fromStdU32String(const std::u32string &s)
1582 { return fromUcs4(s.data(), int(s.size())); }
1583
toStdU32String()1584 inline std::u32string QString::toStdU32String() const
1585 {
1586 std::u32string u32str(length(), char32_t(0));
1587 int len = toUcs4_helper(d->data(), length(), reinterpret_cast<uint*>(&u32str[0]));
1588 u32str.resize(len);
1589 return u32str;
1590 }
1591 #endif
1592
1593 #if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
1594 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QString &);
1595 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QString &);
1596 #endif
1597
1598 Q_DECLARE_SHARED(QString)
Q_DECLARE_OPERATORS_FOR_FLAGS(QString::SectionFlags)1599 Q_DECLARE_OPERATORS_FOR_FLAGS(QString::SectionFlags)
1600
1601
1602 class Q_CORE_EXPORT QStringRef {
1603 const QString *m_string;
1604 int m_position;
1605 int m_size;
1606 public:
1607 typedef QString::size_type size_type;
1608 typedef QString::value_type value_type;
1609 typedef const QChar *const_iterator;
1610 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1611 typedef QString::const_pointer const_pointer;
1612 typedef QString::const_reference const_reference;
1613
1614 // ### Qt 6: make this constructor constexpr, after the destructor is made trivial
1615 inline QStringRef() : m_string(nullptr), m_position(0), m_size(0) {}
1616 inline QStringRef(const QString *string, int position, int size);
1617 inline QStringRef(const QString *string);
1618
1619 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1620 // ### Qt 6: remove all of these, the implicit ones are fine
1621 QStringRef(const QStringRef &other) noexcept
1622 :m_string(other.m_string), m_position(other.m_position), m_size(other.m_size)
1623 {}
1624 QStringRef(QStringRef &&other) noexcept : m_string(other.m_string), m_position(other.m_position), m_size(other.m_size) {}
1625 QStringRef &operator=(QStringRef &&other) noexcept { return *this = other; }
1626 QStringRef &operator=(const QStringRef &other) noexcept
1627 {
1628 m_string = other.m_string; m_position = other.m_position;
1629 m_size = other.m_size; return *this;
1630 }
1631 inline ~QStringRef(){}
1632 #endif // Qt < 6.0.0
1633
1634 inline const QString *string() const { return m_string; }
1635 inline int position() const { return m_position; }
1636 inline int size() const { return m_size; }
1637 inline int count() const { return m_size; }
1638 inline int length() const { return m_size; }
1639
1640 #if QT_STRINGVIEW_LEVEL < 2
1641 int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1642 int indexOf(const QStringRef &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1643 #endif
1644 Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1645 { return int(QtPrivate::findString(*this, from, s, cs)); } // ### Qt6: qsizetype
1646 int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1647 int indexOf(QLatin1String str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1648 #if QT_STRINGVIEW_LEVEL < 2
1649 int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1650 int lastIndexOf(const QString &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1651 #endif
1652 int lastIndexOf(QChar ch, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1653 int lastIndexOf(QLatin1String str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1654 Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1655 { return int(QtPrivate::lastIndexOf(*this, from, s, cs)); } // ### Qt6: qsizetype
1656
1657 #if QT_STRINGVIEW_LEVEL < 2
1658 inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1659 inline bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1660 #endif
1661 inline bool contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1662 inline bool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1663 inline bool contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1664
1665 int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1666 int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1667 int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1668
1669 #if QT_DEPRECATED_SINCE(5, 15)
1670 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use Qt::SplitBehavior variant instead")
1671 QVector<QStringRef> split(const QString &sep, QString::SplitBehavior behavior,
1672 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1673 Q_REQUIRED_RESULT QT_DEPRECATED_VERSION_X_5_15("Use Qt::SplitBehavior variant instead")
1674 QVector<QStringRef> split(QChar sep, QString::SplitBehavior behavior,
1675 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1676 #endif // 5.15 deprecations
1677
1678 Q_REQUIRED_RESULT
1679 QVector<QStringRef> split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
1680 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1681 Q_REQUIRED_RESULT
1682 QVector<QStringRef> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
1683 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1684
1685 Q_REQUIRED_RESULT QStringRef left(int n) const;
1686 Q_REQUIRED_RESULT QStringRef right(int n) const;
1687 Q_REQUIRED_RESULT QStringRef mid(int pos, int n = -1) const;
1688 Q_REQUIRED_RESULT QStringRef chopped(int n) const
1689 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return left(size() - n); }
1690
1691 void truncate(int pos) noexcept { m_size = qBound(0, pos, m_size); }
1692 void chop(int n) noexcept
1693 {
1694 if (n >= m_size)
1695 m_size = 0;
1696 else if (n > 0)
1697 m_size -= n;
1698 }
1699
1700 bool isRightToLeft() const;
1701
1702 Q_REQUIRED_RESULT bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1703 { return QtPrivate::startsWith(*this, s, cs); }
1704 bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1705 bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1706 #if QT_STRINGVIEW_LEVEL < 2
1707 bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1708 bool startsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1709 #endif
1710
1711 Q_REQUIRED_RESULT bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1712 { return QtPrivate::endsWith(*this, s, cs); }
1713 bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1714 bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1715 #if QT_STRINGVIEW_LEVEL < 2
1716 bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1717 bool endsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
1718 #endif
1719
1720 inline QStringRef &operator=(const QString *string);
1721
1722 inline const QChar *unicode() const
1723 {
1724 if (!m_string)
1725 return reinterpret_cast<const QChar *>(QString::Data::sharedNull()->data());
1726 return m_string->unicode() + m_position;
1727 }
1728 inline const QChar *data() const { return unicode(); }
1729 inline const QChar *constData() const { return unicode(); }
1730
1731 inline const_iterator begin() const { return unicode(); }
1732 inline const_iterator cbegin() const { return unicode(); }
1733 inline const_iterator constBegin() const { return unicode(); }
1734 inline const_iterator end() const { return unicode() + size(); }
1735 inline const_iterator cend() const { return unicode() + size(); }
1736 inline const_iterator constEnd() const { return unicode() + size(); }
1737 inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
1738 inline const_reverse_iterator crbegin() const { return rbegin(); }
1739 inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
1740 inline const_reverse_iterator crend() const { return rend(); }
1741
1742 #if QT_DEPRECATED_SINCE(5, 0)
1743 Q_REQUIRED_RESULT QT_DEPRECATED QByteArray toAscii() const
1744 { return toLatin1(); }
1745 #endif
1746 Q_REQUIRED_RESULT QByteArray toLatin1() const;
1747 Q_REQUIRED_RESULT QByteArray toUtf8() const;
1748 Q_REQUIRED_RESULT QByteArray toLocal8Bit() const;
1749 Q_REQUIRED_RESULT QVector<uint> toUcs4() const;
1750
1751 inline void clear() { m_string = nullptr; m_position = m_size = 0; }
1752 QString toString() const;
1753 inline bool isEmpty() const { return m_size == 0; }
1754 inline bool isNull() const { return m_string == nullptr || m_string->isNull(); }
1755
1756 QStringRef appendTo(QString *string) const;
1757
1758 inline const QChar at(int i) const
1759 { Q_ASSERT(uint(i) < uint(size())); return m_string->at(i + m_position); }
1760 QChar operator[](int i) const { return at(i); }
1761 Q_REQUIRED_RESULT QChar front() const { return at(0); }
1762 Q_REQUIRED_RESULT QChar back() const { return at(size() - 1); }
1763
1764 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1765 // ASCII compatibility
1766 inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
1767 inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
1768 inline QT_ASCII_CAST_WARN bool operator<(const char *s) const;
1769 inline QT_ASCII_CAST_WARN bool operator<=(const char *s) const;
1770 inline QT_ASCII_CAST_WARN bool operator>(const char *s) const;
1771 inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const;
1772 #endif
1773
1774 int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1775 int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1776 int compare(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
1777 { return QtPrivate::compareStrings(*this, QStringView(&c, 1), cs); }
1778 int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
1779 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1780 int compare(const QByteArray &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
1781 { return QString::compare_helper(unicode(), size(), s.data(), qstrnlen(s.data(), s.size()), cs); }
1782 #endif
1783 static int compare(const QStringRef &s1, const QString &s2,
1784 Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
1785 static int compare(const QStringRef &s1, const QStringRef &s2,
1786 Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
1787 static int compare(const QStringRef &s1, QLatin1String s2,
1788 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
1789
1790 int localeAwareCompare(const QString &s) const;
1791 int localeAwareCompare(const QStringRef &s) const;
1792 int localeAwareCompare(QStringView str) const;
1793 static int localeAwareCompare(const QStringRef &s1, const QString &s2);
1794 static int localeAwareCompare(const QStringRef &s1, const QStringRef &s2);
1795 static int localeAwareCompare(QStringView s1, QStringView s2);
1796
1797 Q_REQUIRED_RESULT QStringRef trimmed() const;
1798 short toShort(bool *ok = nullptr, int base = 10) const;
1799 ushort toUShort(bool *ok = nullptr, int base = 10) const;
1800 int toInt(bool *ok = nullptr, int base = 10) const;
1801 uint toUInt(bool *ok = nullptr, int base = 10) const;
1802 long toLong(bool *ok = nullptr, int base = 10) const;
1803 ulong toULong(bool *ok = nullptr, int base = 10) const;
1804 qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
1805 qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
1806 float toFloat(bool *ok = nullptr) const;
1807 double toDouble(bool *ok = nullptr) const;
1808 };
1809 Q_DECLARE_TYPEINFO(QStringRef, Q_PRIMITIVE_TYPE);
1810
1811 inline QStringRef &QStringRef::operator=(const QString *aString)
1812 { m_string = aString; m_position = 0; m_size = aString?aString->size():0; return *this; }
1813
QStringRef(const QString * aString,int aPosition,int aSize)1814 inline QStringRef::QStringRef(const QString *aString, int aPosition, int aSize)
1815 :m_string(aString), m_position(aPosition), m_size(aSize){}
1816
QStringRef(const QString * aString)1817 inline QStringRef::QStringRef(const QString *aString)
1818 :m_string(aString), m_position(0), m_size(aString?aString->size() : 0){}
1819
1820 // QStringRef <> QStringRef
1821 Q_CORE_EXPORT bool operator==(const QStringRef &s1, const QStringRef &s2) noexcept;
1822 inline bool operator!=(const QStringRef &s1, const QStringRef &s2) noexcept
1823 { return !(s1 == s2); }
1824 Q_CORE_EXPORT bool operator<(const QStringRef &s1, const QStringRef &s2) noexcept;
1825 inline bool operator>(const QStringRef &s1, const QStringRef &s2) noexcept
1826 { return s2 < s1; }
1827 inline bool operator<=(const QStringRef &s1, const QStringRef &s2) noexcept
1828 { return !(s1 > s2); }
1829 inline bool operator>=(const QStringRef &s1, const QStringRef &s2) noexcept
1830 { return !(s1 < s2); }
1831
1832 // QString <> QStringRef
1833 Q_CORE_EXPORT bool operator==(const QString &lhs, const QStringRef &rhs) noexcept;
1834 inline bool operator!=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) != 0; }
1835 inline bool operator< (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) < 0; }
1836 inline bool operator> (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) > 0; }
1837 inline bool operator<=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) <= 0; }
1838 inline bool operator>=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(rhs) >= 0; }
1839
1840 inline bool operator==(const QStringRef &lhs, const QString &rhs) noexcept { return rhs == lhs; }
1841 inline bool operator!=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs != lhs; }
1842 inline bool operator< (const QStringRef &lhs, const QString &rhs) noexcept { return rhs > lhs; }
1843 inline bool operator> (const QStringRef &lhs, const QString &rhs) noexcept { return rhs < lhs; }
1844 inline bool operator<=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs >= lhs; }
1845 inline bool operator>=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs <= lhs; }
1846
1847 #if QT_STRINGVIEW_LEVEL < 2
compare(const QStringRef & s,Qt::CaseSensitivity cs)1848 inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const noexcept
1849 { return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
1850 #endif
compare(QStringView s,Qt::CaseSensitivity cs)1851 inline int QString::compare(QStringView s, Qt::CaseSensitivity cs) const noexcept
1852 { return -s.compare(*this, cs); }
compare(const QString & s1,const QStringRef & s2,Qt::CaseSensitivity cs)1853 inline int QString::compare(const QString &s1, const QStringRef &s2, Qt::CaseSensitivity cs) noexcept
1854 { return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
compare(const QString & s,Qt::CaseSensitivity cs)1855 inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const noexcept
1856 { return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
compare(const QStringRef & s,Qt::CaseSensitivity cs)1857 inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const noexcept
1858 { return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
compare(QLatin1String s,Qt::CaseSensitivity cs)1859 inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
1860 { return QString::compare_helper(constData(), length(), s, cs); }
compare(const QStringRef & s1,const QString & s2,Qt::CaseSensitivity cs)1861 inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs) noexcept
1862 { return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
compare(const QStringRef & s1,const QStringRef & s2,Qt::CaseSensitivity cs)1863 inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs) noexcept
1864 { return QString::compare_helper(s1.constData(), s1.length(), s2.constData(), s2.length(), cs); }
compare(const QStringRef & s1,QLatin1String s2,Qt::CaseSensitivity cs)1865 inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs) noexcept
1866 { return QString::compare_helper(s1.constData(), s1.length(), s2, cs); }
1867
1868 // QLatin1String <> QStringRef
1869 Q_CORE_EXPORT bool operator==(QLatin1String lhs, const QStringRef &rhs) noexcept;
1870 inline bool operator!=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) != 0; }
1871 inline bool operator< (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) > 0; }
1872 inline bool operator> (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) < 0; }
1873 inline bool operator<=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) >= 0; }
1874 inline bool operator>=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(lhs) <= 0; }
1875
1876 inline bool operator==(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs == lhs; }
1877 inline bool operator!=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs != lhs; }
1878 inline bool operator< (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs > lhs; }
1879 inline bool operator> (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs < lhs; }
1880 inline bool operator<=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs >= lhs; }
1881 inline bool operator>=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs <= lhs; }
1882
1883 // QChar <> QString
1884 inline bool operator==(QChar lhs, const QString &rhs) noexcept
1885 { return rhs.size() == 1 && lhs == rhs.front(); }
1886 inline bool operator< (QChar lhs, const QString &rhs) noexcept
1887 { return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; }
1888 inline bool operator> (QChar lhs, const QString &rhs) noexcept
1889 { return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; }
1890
1891 inline bool operator!=(QChar lhs, const QString &rhs) noexcept { return !(lhs == rhs); }
1892 inline bool operator<=(QChar lhs, const QString &rhs) noexcept { return !(lhs > rhs); }
1893 inline bool operator>=(QChar lhs, const QString &rhs) noexcept { return !(lhs < rhs); }
1894
1895 inline bool operator==(const QString &lhs, QChar rhs) noexcept { return rhs == lhs; }
1896 inline bool operator!=(const QString &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
1897 inline bool operator< (const QString &lhs, QChar rhs) noexcept { return rhs > lhs; }
1898 inline bool operator> (const QString &lhs, QChar rhs) noexcept { return rhs < lhs; }
1899 inline bool operator<=(const QString &lhs, QChar rhs) noexcept { return !(rhs < lhs); }
1900 inline bool operator>=(const QString &lhs, QChar rhs) noexcept { return !(rhs > lhs); }
1901
1902 // QChar <> QStringRef
1903 inline bool operator==(QChar lhs, const QStringRef &rhs) noexcept
1904 { return rhs.size() == 1 && lhs == rhs.front(); }
1905 inline bool operator< (QChar lhs, const QStringRef &rhs) noexcept
1906 { return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) < 0; }
1907 inline bool operator> (QChar lhs, const QStringRef &rhs) noexcept
1908 { return QString::compare_helper(&lhs, 1, rhs.data(), rhs.size()) > 0; }
1909
1910 inline bool operator!=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs == rhs); }
1911 inline bool operator<=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs > rhs); }
1912 inline bool operator>=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs < rhs); }
1913
1914 inline bool operator==(const QStringRef &lhs, QChar rhs) noexcept { return rhs == lhs; }
1915 inline bool operator!=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
1916 inline bool operator< (const QStringRef &lhs, QChar rhs) noexcept { return rhs > lhs; }
1917 inline bool operator> (const QStringRef &lhs, QChar rhs) noexcept { return rhs < lhs; }
1918 inline bool operator<=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs < lhs); }
1919 inline bool operator>=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs > lhs); }
1920
1921 // QChar <> QLatin1String
1922 inline bool operator==(QChar lhs, QLatin1String rhs) noexcept
1923 { return rhs.size() == 1 && lhs == rhs.front(); }
1924 inline bool operator< (QChar lhs, QLatin1String rhs) noexcept
1925 { return QString::compare_helper(&lhs, 1, rhs) < 0; }
1926 inline bool operator> (QChar lhs, QLatin1String rhs) noexcept
1927 { return QString::compare_helper(&lhs, 1, rhs) > 0; }
1928
1929 inline bool operator!=(QChar lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
1930 inline bool operator<=(QChar lhs, QLatin1String rhs) noexcept { return !(lhs > rhs); }
1931 inline bool operator>=(QChar lhs, QLatin1String rhs) noexcept { return !(lhs < rhs); }
1932
1933 inline bool operator==(QLatin1String lhs, QChar rhs) noexcept { return rhs == lhs; }
1934 inline bool operator!=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs == lhs); }
1935 inline bool operator< (QLatin1String lhs, QChar rhs) noexcept { return rhs > lhs; }
1936 inline bool operator> (QLatin1String lhs, QChar rhs) noexcept { return rhs < lhs; }
1937 inline bool operator<=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs < lhs); }
1938 inline bool operator>=(QLatin1String lhs, QChar rhs) noexcept { return !(rhs > lhs); }
1939
1940 // QStringView <> QStringView
1941 inline bool operator==(QStringView lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
1942 inline bool operator!=(QStringView lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
1943 inline bool operator< (QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
1944 inline bool operator<=(QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
1945 inline bool operator> (QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
1946 inline bool operator>=(QStringView lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
1947
1948 // QStringView <> QChar
1949 inline bool operator==(QStringView lhs, QChar rhs) noexcept { return lhs == QStringView(&rhs, 1); }
1950 inline bool operator!=(QStringView lhs, QChar rhs) noexcept { return lhs != QStringView(&rhs, 1); }
1951 inline bool operator< (QStringView lhs, QChar rhs) noexcept { return lhs < QStringView(&rhs, 1); }
1952 inline bool operator<=(QStringView lhs, QChar rhs) noexcept { return lhs <= QStringView(&rhs, 1); }
1953 inline bool operator> (QStringView lhs, QChar rhs) noexcept { return lhs > QStringView(&rhs, 1); }
1954 inline bool operator>=(QStringView lhs, QChar rhs) noexcept { return lhs >= QStringView(&rhs, 1); }
1955
1956 inline bool operator==(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) == rhs; }
1957 inline bool operator!=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) != rhs; }
1958 inline bool operator< (QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) < rhs; }
1959 inline bool operator<=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) <= rhs; }
1960 inline bool operator> (QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) > rhs; }
1961 inline bool operator>=(QChar lhs, QStringView rhs) noexcept { return QStringView(&lhs, 1) >= rhs; }
1962
1963 // QStringView <> QLatin1String
1964 inline bool operator==(QStringView lhs, QLatin1String rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
1965 inline bool operator!=(QStringView lhs, QLatin1String rhs) noexcept { return !(lhs == rhs); }
1966 inline bool operator< (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
1967 inline bool operator<=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
1968 inline bool operator> (QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
1969 inline bool operator>=(QStringView lhs, QLatin1String rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
1970
1971 inline bool operator==(QLatin1String lhs, QStringView rhs) noexcept { return lhs.size() == rhs.size() && QtPrivate::compareStrings(lhs, rhs) == 0; }
1972 inline bool operator!=(QLatin1String lhs, QStringView rhs) noexcept { return !(lhs == rhs); }
1973 inline bool operator< (QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) < 0; }
1974 inline bool operator<=(QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) <= 0; }
1975 inline bool operator> (QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) > 0; }
1976 inline bool operator>=(QLatin1String lhs, QStringView rhs) noexcept { return QtPrivate::compareStrings(lhs, rhs) >= 0; }
1977
1978 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
1979 // QStringRef <> QByteArray
1980 inline QT_ASCII_CAST_WARN bool operator==(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) == 0; }
1981 inline QT_ASCII_CAST_WARN bool operator!=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) != 0; }
1982 inline QT_ASCII_CAST_WARN bool operator< (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) < 0; }
1983 inline QT_ASCII_CAST_WARN bool operator> (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) > 0; }
1984 inline QT_ASCII_CAST_WARN bool operator<=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) <= 0; }
1985 inline QT_ASCII_CAST_WARN bool operator>=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(rhs) >= 0; }
1986
1987 inline QT_ASCII_CAST_WARN bool operator==(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) == 0; }
1988 inline QT_ASCII_CAST_WARN bool operator!=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) != 0; }
1989 inline QT_ASCII_CAST_WARN bool operator< (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) > 0; }
1990 inline QT_ASCII_CAST_WARN bool operator> (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) < 0; }
1991 inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) >= 0; }
1992 inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(lhs) <= 0; }
1993
1994 // QStringRef <> const char *
1995 inline QT_ASCII_CAST_WARN bool QStringRef::operator==(const char *s) const
1996 { return QString::compare_helper(constData(), size(), s, -1) == 0; }
1997 inline QT_ASCII_CAST_WARN bool QStringRef::operator!=(const char *s) const
1998 { return QString::compare_helper(constData(), size(), s, -1) != 0; }
1999 inline QT_ASCII_CAST_WARN bool QStringRef::operator<(const char *s) const
2000 { return QString::compare_helper(constData(), size(), s, -1) < 0; }
2001 inline QT_ASCII_CAST_WARN bool QStringRef::operator<=(const char *s) const
2002 { return QString::compare_helper(constData(), size(), s, -1) <= 0; }
2003 inline QT_ASCII_CAST_WARN bool QStringRef::operator>(const char *s) const
2004 { return QString::compare_helper(constData(), size(), s, -1) > 0; }
2005 inline QT_ASCII_CAST_WARN bool QStringRef::operator>=(const char *s) const
2006 { return QString::compare_helper(constData(), size(), s, -1) >= 0; }
2007
2008 inline QT_ASCII_CAST_WARN bool operator==(const char *s1, const QStringRef &s2)
2009 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) == 0; }
2010 inline QT_ASCII_CAST_WARN bool operator!=(const char *s1, const QStringRef &s2)
2011 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) != 0; }
2012 inline QT_ASCII_CAST_WARN bool operator<(const char *s1, const QStringRef &s2)
2013 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) > 0; }
2014 inline QT_ASCII_CAST_WARN bool operator<=(const char *s1, const QStringRef &s2)
2015 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
2016 inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QStringRef &s2)
2017 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) < 0; }
2018 inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2)
2019 { return QString::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; }
2020 #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
2021
localeAwareCompare(const QStringRef & s)2022 inline int QString::localeAwareCompare(const QStringRef &s) const
2023 { return localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
localeAwareCompare(const QString & s1,const QStringRef & s2)2024 inline int QString::localeAwareCompare(const QString& s1, const QStringRef& s2)
2025 { return localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
localeAwareCompare(const QString & s)2026 inline int QStringRef::localeAwareCompare(const QString &s) const
2027 { return QString::localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
localeAwareCompare(const QStringRef & s)2028 inline int QStringRef::localeAwareCompare(const QStringRef &s) const
2029 { return QString::localeAwareCompare_helper(constData(), length(), s.constData(), s.length()); }
localeAwareCompare(QStringView s)2030 inline int QStringRef::localeAwareCompare(QStringView s) const
2031 { return QString::localeAwareCompare_helper(constData(), length(), s.data(), int(s.size())); }
localeAwareCompare(const QStringRef & s1,const QString & s2)2032 inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QString &s2)
2033 { return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
localeAwareCompare(const QStringRef & s1,const QStringRef & s2)2034 inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef &s2)
2035 { return QString::localeAwareCompare_helper(s1.constData(), s1.length(), s2.constData(), s2.length()); }
localeAwareCompare(QStringView s1,QStringView s2)2036 inline int QStringRef::localeAwareCompare(QStringView s1, QStringView s2)
2037 { return QString::localeAwareCompare_helper(s1.data(), int(s1.size()), s2.data(), int(s2.size())); }
2038
2039 #if QT_STRINGVIEW_LEVEL < 2
contains(const QString & s,Qt::CaseSensitivity cs)2040 inline bool QStringRef::contains(const QString &s, Qt::CaseSensitivity cs) const
2041 { return indexOf(s, 0, cs) != -1; }
contains(const QStringRef & s,Qt::CaseSensitivity cs)2042 inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
2043 { return indexOf(s, 0, cs) != -1; }
2044 #endif
contains(QLatin1String s,Qt::CaseSensitivity cs)2045 inline bool QStringRef::contains(QLatin1String s, Qt::CaseSensitivity cs) const
2046 { return indexOf(s, 0, cs) != -1; }
contains(QChar c,Qt::CaseSensitivity cs)2047 inline bool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const
2048 { return indexOf(c, 0, cs) != -1; }
contains(QStringView s,Qt::CaseSensitivity cs)2049 inline bool QStringRef::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
2050 { return indexOf(s, 0, cs) != -1; }
2051
insert(int i,const QStringRef & s)2052 inline QString &QString::insert(int i, const QStringRef &s)
2053 { return insert(i, s.constData(), s.length()); }
2054
2055 #if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
2056 inline QString operator+(const QString &s1, const QStringRef &s2)
2057 { QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2058 inline QString operator+(const QStringRef &s1, const QString &s2)
2059 { QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2060 inline QString operator+(const QStringRef &s1, QLatin1String s2)
2061 { QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2062 inline QString operator+(QLatin1String s1, const QStringRef &s2)
2063 { QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2064 inline QString operator+(const QStringRef &s1, const QStringRef &s2)
2065 { QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
2066 inline QString operator+(const QStringRef &s1, QChar s2)
2067 { QString t; t.reserve(s1.size() + 1); t += s1; t += s2; return t; }
2068 inline QString operator+(QChar s1, const QStringRef &s2)
2069 { QString t; t.reserve(1 + s2.size()); t += s1; t += s2; return t; }
2070 #endif // !(QT_USE_FAST_OPERATOR_PLUS || QT_USE_QSTRINGBUILDER)
2071
2072 namespace Qt {
2073 #if QT_DEPRECATED_SINCE(5, 0)
escape(const QString & plain)2074 QT_DEPRECATED inline QString escape(const QString &plain) {
2075 return plain.toHtmlEscaped();
2076 }
2077 #endif
2078 }
2079
2080 namespace QtPrivate {
2081 // used by qPrintable() and qUtf8Printable() macros
asString(const QString & s)2082 inline const QString &asString(const QString &s) { return s; }
asString(QString && s)2083 inline QString &&asString(QString &&s) { return std::move(s); }
2084 }
2085
2086 //
2087 // QStringView::arg() implementation
2088 //
2089
2090 namespace QtPrivate {
2091
2092 struct ArgBase {
2093 enum Tag : uchar { L1, U8, U16 } tag;
2094 };
2095
2096 struct QStringViewArg : ArgBase {
2097 QStringView string;
2098 QStringViewArg() = default;
QStringViewArgQStringViewArg2099 Q_DECL_CONSTEXPR explicit QStringViewArg(QStringView v) noexcept : ArgBase{U16}, string{v} {}
2100 };
2101
2102 struct QLatin1StringArg : ArgBase {
2103 QLatin1String string;
2104 QLatin1StringArg() = default;
QLatin1StringArgQLatin1StringArg2105 Q_DECL_CONSTEXPR explicit QLatin1StringArg(QLatin1String v) noexcept : ArgBase{L1}, string{v} {}
2106 };
2107
2108 Q_REQUIRED_RESULT Q_CORE_EXPORT QString argToQString(QStringView pattern, size_t n, const ArgBase **args);
2109 Q_REQUIRED_RESULT Q_CORE_EXPORT QString argToQString(QLatin1String pattern, size_t n, const ArgBase **args);
2110
2111 template <typename StringView, typename...Args>
argToQStringDispatch(StringView pattern,const Args &...args)2112 Q_REQUIRED_RESULT Q_ALWAYS_INLINE QString argToQStringDispatch(StringView pattern, const Args &...args)
2113 {
2114 const ArgBase *argBases[] = {&args..., /* avoid zero-sized array */ nullptr};
2115 return QtPrivate::argToQString(pattern, sizeof...(Args), argBases);
2116 }
2117
qStringLikeToArg(const QString & s)2118 inline QStringViewArg qStringLikeToArg(const QString &s) noexcept { return QStringViewArg{qToStringViewIgnoringNull(s)}; }
qStringLikeToArg(QStringView s)2119 Q_DECL_CONSTEXPR inline QStringViewArg qStringLikeToArg(QStringView s) noexcept { return QStringViewArg{s}; }
qStringLikeToArg(const QChar & c)2120 inline QStringViewArg qStringLikeToArg(const QChar &c) noexcept { return QStringViewArg{QStringView{&c, 1}}; }
qStringLikeToArg(QLatin1String s)2121 Q_DECL_CONSTEXPR inline QLatin1StringArg qStringLikeToArg(QLatin1String s) noexcept { return QLatin1StringArg{s}; }
2122
2123 } // namespace QtPrivate
2124
2125 template <typename...Args>
2126 Q_ALWAYS_INLINE
arg(Args &&...args)2127 QString QStringView::arg(Args &&...args) const
2128 {
2129 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
2130 }
2131
2132 template <typename...Args>
2133 Q_ALWAYS_INLINE
arg(Args &&...args)2134 QString QLatin1String::arg(Args &&...args) const
2135 {
2136 return QtPrivate::argToQStringDispatch(*this, QtPrivate::qStringLikeToArg(args)...);
2137 }
2138
count(QChar c,Qt::CaseSensitivity cs)2139 inline qsizetype QStringView::count(QChar c, Qt::CaseSensitivity cs) const noexcept
2140 { return toString().count(c, cs); }
count(QStringView s,Qt::CaseSensitivity cs)2141 inline qsizetype QStringView::count(QStringView s, Qt::CaseSensitivity cs) const noexcept
2142 { return toString().count(s.toString(), cs); }
2143
toShort(bool * ok,int base)2144 inline short QStringView::toShort(bool *ok, int base) const
2145 { return toString().toShort(ok, base); }
toUShort(bool * ok,int base)2146 inline ushort QStringView::toUShort(bool *ok, int base) const
2147 { return toString().toUShort(ok, base); }
toInt(bool * ok,int base)2148 inline int QStringView::toInt(bool *ok, int base) const
2149 { return toString().toInt(ok, base); }
toUInt(bool * ok,int base)2150 inline uint QStringView::toUInt(bool *ok, int base) const
2151 { return toString().toUInt(ok, base); }
toLong(bool * ok,int base)2152 inline long QStringView::toLong(bool *ok, int base) const
2153 { return toString().toLong(ok, base); }
toULong(bool * ok,int base)2154 inline ulong QStringView::toULong(bool *ok, int base) const
2155 { return toString().toULong(ok, base); }
toLongLong(bool * ok,int base)2156 inline qlonglong QStringView::toLongLong(bool *ok, int base) const
2157 { return toString().toLongLong(ok, base); }
toULongLong(bool * ok,int base)2158 inline qulonglong QStringView::toULongLong(bool *ok, int base) const
2159 { return toString().toULongLong(ok, base); }
toFloat(bool * ok)2160 inline float QStringView::toFloat(bool *ok) const
2161 { return toString().toFloat(ok); }
toDouble(bool * ok)2162 inline double QStringView::toDouble(bool *ok) const
2163 { return toString().toDouble(ok); }
2164
2165 QT_END_NAMESPACE
2166
2167 #if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
2168 #include <QtCore/qstringbuilder.h>
2169 #endif
2170
2171 #endif // QSTRING_H
2172