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 &reg, int start, int end = -1, SectionFlags flags = SectionDefault) const;
461 #endif
462 #if QT_CONFIG(regularexpression)
463     QString section(const QRegularExpression &re, int start, int end = -1, SectionFlags flags = SectionDefault) const;
464 #endif
465     Q_REQUIRED_RESULT QString left(int n) const;
466     Q_REQUIRED_RESULT QString right(int n) const;
467     Q_REQUIRED_RESULT QString mid(int position, int n = -1) const;
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