1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2019 Intel Corporation.
3// Copyright (C) 2019 Mail.ru Group.
4// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
5// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
6
7#ifndef QSTRINGREF_H
8#define QSTRINGREF_H
9
10#if defined(QT_NO_CAST_FROM_ASCII) && defined(QT_RESTRICTED_CAST_FROM_ASCII)
11#error QT_NO_CAST_FROM_ASCII and QT_RESTRICTED_CAST_FROM_ASCII must not be defined at the same time
12#endif
13
14#include <QtCore/qchar.h>
15#include <QtCore/qbytearray.h>
16#include <QtCore/qarraydata.h>
17#include <QtCore/qnamespace.h>
18#include <QtCore/qhashfunctions.h>
19#include <QtCore/qstringliteral.h>
20#include <QtCore/qstringalgorithms.h>
21#include <QtCore/qstringview.h>
22#include <QtCore/qstringtokenizer.h>
23
24#include <QtCore5Compat/qcore5global.h>
25
26#include <iterator>
27
28#ifdef truncate
29#error qstringref.h must be included before any header file that defines truncate
30#endif
31
32QT_BEGIN_NAMESPACE
33
34class Q_CORE5COMPAT_EXPORT QStringRef
35{
36 const QString *m_string;
37 int m_position;
38 int m_size;
39public:
40 typedef QString::size_type size_type;
41 typedef QString::value_type value_type;
42 typedef const QChar *const_iterator;
43 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
44 typedef QString::const_pointer const_pointer;
45 typedef QString::const_reference const_reference;
46
47 constexpr QStringRef() noexcept
48 : m_string(nullptr), m_position(0), m_size(0) { }
49 inline QStringRef(const QString *string, int position, int size);
50 inline QStringRef(const QString *string);
51
52 inline const QString *string() const { return m_string; }
53 inline int position() const { return m_position; }
54 inline int size() const { return m_size; }
55 inline int count() const { return m_size; }
56 inline int length() const { return m_size; }
57
58 int indexOf(const QString &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
59 int indexOf(const QStringRef &str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
60 Q_REQUIRED_RESULT int indexOf(QStringView s, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
61 { return int(QtPrivate::findString(haystack: *this, from, needle: s, cs)); } // ### Qt6: qsizetype
62 int indexOf(QChar ch, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
63 int indexOf(QLatin1String str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
64 int lastIndexOf(const QStringRef &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
65 int lastIndexOf(const QString &str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
66 int lastIndexOf(QChar ch, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
67 int lastIndexOf(QLatin1String str, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
68 Q_REQUIRED_RESULT int lastIndexOf(QStringView s, int from = -1, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
69 { return int(QtPrivate::lastIndexOf(haystack: *this, from, needle: s, cs)); } // ### Qt6: qsizetype
70
71 inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
72 inline bool contains(const QStringRef &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
73 inline bool contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
74 inline bool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
75 inline bool contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
76
77 int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
78 int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
79 int count(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
80
81 Q_REQUIRED_RESULT
82 QList<QStringRef> split(const QString &sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
83 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
84 Q_REQUIRED_RESULT
85 QList<QStringRef> split(QChar sep, Qt::SplitBehavior behavior = Qt::KeepEmptyParts,
86 Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
87
88 Q_REQUIRED_RESULT QStringRef left(int n) const;
89 Q_REQUIRED_RESULT QStringRef right(int n) const;
90 Q_REQUIRED_RESULT QStringRef mid(int pos, int n = -1) const;
91 Q_REQUIRED_RESULT QStringRef chopped(int n) const
92 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return left(n: size() - n); }
93
94 void truncate(int pos) noexcept { m_size = qBound(min: 0, val: pos, max: m_size); }
95 void chop(int n) noexcept
96 {
97 if (n >= m_size)
98 m_size = 0;
99 else if (n > 0)
100 m_size -= n;
101 }
102
103 bool isRightToLeft() const;
104
105 Q_REQUIRED_RESULT bool startsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
106 { return QtPrivate::startsWith(haystack: *this, needle: s, cs); }
107 bool startsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
108 bool startsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
109 bool startsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
110 bool startsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
111
112 Q_REQUIRED_RESULT bool endsWith(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
113 { return QtPrivate::endsWith(haystack: *this, needle: s, cs); }
114 bool endsWith(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
115 bool endsWith(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
116 bool endsWith(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
117 bool endsWith(const QStringRef &c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
118
119 inline operator QStringView() const {
120 if (!m_string)
121 return {};
122 return QStringView(m_string->data() + m_position, m_size);
123 }
124 inline QStringRef &operator=(const QString *string);
125
126 inline const QChar *unicode() const
127 {
128 static const char16_t _empty = 0;
129 if (!m_string)
130 return reinterpret_cast<const QChar *>(&_empty);
131 return m_string->unicode() + m_position;
132 }
133 inline const QChar *data() const { return unicode(); }
134 inline const QChar *constData() const { return unicode(); }
135
136 inline const_iterator begin() const { return unicode(); }
137 inline const_iterator cbegin() const { return unicode(); }
138 inline const_iterator constBegin() const { return unicode(); }
139 inline const_iterator end() const { return unicode() + size(); }
140 inline const_iterator cend() const { return unicode() + size(); }
141 inline const_iterator constEnd() const { return unicode() + size(); }
142 inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
143 inline const_reverse_iterator crbegin() const { return rbegin(); }
144 inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
145 inline const_reverse_iterator crend() const { return rend(); }
146
147 Q_REQUIRED_RESULT QByteArray toLatin1() const;
148 Q_REQUIRED_RESULT QByteArray toUtf8() const;
149 Q_REQUIRED_RESULT QByteArray toLocal8Bit() const;
150 Q_REQUIRED_RESULT QList<uint> toUcs4() const;
151
152 inline void clear() { m_string = nullptr; m_position = m_size = 0; }
153 QString toString() const;
154 inline bool isEmpty() const { return m_size == 0; }
155 inline bool isNull() const { return m_string == nullptr || m_string->isNull(); }
156
157 QStringRef appendTo(QString *string) const;
158
159 inline const QChar at(int i) const
160 { Q_ASSERT(uint(i) < uint(size())); return m_string->at(i: i + m_position); }
161 QChar operator[](int i) const { return at(i); }
162 Q_REQUIRED_RESULT QChar front() const { return at(i: 0); }
163 Q_REQUIRED_RESULT QChar back() const { return at(i: size() - 1); }
164
165#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
166 // ASCII compatibility
167 QT_ASCII_CAST_WARN inline bool operator==(const char *s) const;
168 QT_ASCII_CAST_WARN inline bool operator!=(const char *s) const;
169 QT_ASCII_CAST_WARN inline bool operator<(const char *s) const;
170 QT_ASCII_CAST_WARN inline bool operator<=(const char *s) const;
171 QT_ASCII_CAST_WARN inline bool operator>(const char *s) const;
172 QT_ASCII_CAST_WARN inline bool operator>=(const char *s) const;
173#endif
174
175 int compare(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
176 int compare(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
177 int compare(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
178 { return QtPrivate::compareStrings(lhs: *this, rhs: QStringView(&c, 1), cs); }
179 int compare(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
180#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
181 int compare(const QByteArray &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
182 { return QStringRef::compare_helper(data1: unicode(), length1: size(), data2: s.data(), length2: qstrnlen(str: s.data(), maxlen: s.size()), cs); }
183#endif
184 static int compare(const QStringRef &s1, const QString &s2,
185 Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
186 static int compare(const QStringRef &s1, const QStringRef &s2,
187 Qt::CaseSensitivity = Qt::CaseSensitive) noexcept;
188 static int compare(const QStringRef &s1, QLatin1String s2,
189 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
190
191 int localeAwareCompare(const QString &s) const;
192 int localeAwareCompare(const QStringRef &s) const;
193 static int localeAwareCompare(const QStringRef &s1, const QString &s2);
194 static int localeAwareCompare(const QStringRef &s1, const QStringRef &s2);
195
196 Q_REQUIRED_RESULT QStringRef trimmed() const;
197 short toShort(bool *ok = nullptr, int base = 10) const;
198 ushort toUShort(bool *ok = nullptr, int base = 10) const;
199 int toInt(bool *ok = nullptr, int base = 10) const;
200 uint toUInt(bool *ok = nullptr, int base = 10) const;
201 long toLong(bool *ok = nullptr, int base = 10) const;
202 ulong toULong(bool *ok = nullptr, int base = 10) const;
203 qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
204 qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
205 float toFloat(bool *ok = nullptr) const;
206 double toDouble(bool *ok = nullptr) const;
207
208 friend inline bool operator==(QChar, const QStringRef &) noexcept;
209 friend inline bool operator<(QChar, const QStringRef &) noexcept;
210 friend inline bool operator>(QChar, const QStringRef &) noexcept;
211
212#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
213 friend inline bool operator==(const char *s1, const QStringRef &s2);
214 friend inline bool operator!=(const char *s1, const QStringRef &s2);
215 friend inline bool operator<(const char *s1, const QStringRef &s2);
216 friend inline bool operator>(const char *s1, const QStringRef &s2);
217 friend inline bool operator<=(const char *s1, const QStringRef &s2);
218 friend inline bool operator>=(const char *s1, const QStringRef &s2);
219#endif
220
221private:
222 static int compare_helper(const QChar *data1, qsizetype length1,
223 const QChar *data2, qsizetype length2,
224 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
225 static int compare_helper(const QChar *data1, qsizetype length1,
226 const char *data2, qsizetype length2,
227 Qt::CaseSensitivity cs = Qt::CaseSensitive);
228 static int compare_helper(const QChar *data1, qsizetype length1,
229 QLatin1String s2,
230 Qt::CaseSensitivity cs = Qt::CaseSensitive) noexcept;
231};
232Q_DECLARE_TYPEINFO(QStringRef, Q_PRIMITIVE_TYPE);
233
234namespace QtPrivate {
235namespace Tok {
236 template <> struct ViewForImpl<QStringRef> : ViewForImpl<QStringView> {};
237 } // namespace Tok
238} // namespace QtPrivate
239
240inline Q_DECL_PURE_FUNCTION size_t qHash(const QStringRef &key, size_t seed = 0) noexcept
241{
242 return qHash(key: QStringView { key }, seed);
243}
244QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QStringRef)
245
246inline QStringRef &QStringRef::operator=(const QString *aString)
247{ m_string = aString; m_position = 0; m_size = aString ? int(aString->size()) : 0; return *this; }
248
249inline QStringRef::QStringRef(const QString *aString, int aPosition, int aSize)
250 :m_string(aString), m_position(aPosition), m_size(aSize){}
251
252inline QStringRef::QStringRef(const QString *aString)
253 :m_string(aString), m_position(0), m_size(aString ? int(aString->size()) : 0){}
254
255// QStringRef <> QStringRef
256Q_CORE5COMPAT_EXPORT bool operator==(const QStringRef &s1, const QStringRef &s2) noexcept;
257inline bool operator!=(const QStringRef &s1, const QStringRef &s2) noexcept
258{ return !(s1 == s2); }
259Q_CORE5COMPAT_EXPORT bool operator<(const QStringRef &s1, const QStringRef &s2) noexcept;
260inline bool operator>(const QStringRef &s1, const QStringRef &s2) noexcept
261{ return s2 < s1; }
262inline bool operator<=(const QStringRef &s1, const QStringRef &s2) noexcept
263{ return !(s1 > s2); }
264inline bool operator>=(const QStringRef &s1, const QStringRef &s2) noexcept
265{ return !(s1 < s2); }
266
267// QString <> QStringRef
268Q_CORE5COMPAT_EXPORT bool operator==(const QString &lhs, const QStringRef &rhs) noexcept;
269inline bool operator!=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(s: rhs) != 0; }
270inline bool operator< (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(s: rhs) < 0; }
271inline bool operator> (const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(s: rhs) > 0; }
272inline bool operator<=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(s: rhs) <= 0; }
273inline bool operator>=(const QString &lhs, const QStringRef &rhs) noexcept { return lhs.compare(s: rhs) >= 0; }
274
275inline bool operator==(const QStringRef &lhs, const QString &rhs) noexcept { return rhs == lhs; }
276inline bool operator!=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs != lhs; }
277inline bool operator< (const QStringRef &lhs, const QString &rhs) noexcept { return rhs > lhs; }
278inline bool operator> (const QStringRef &lhs, const QString &rhs) noexcept { return rhs < lhs; }
279inline bool operator<=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs >= lhs; }
280inline bool operator>=(const QStringRef &lhs, const QString &rhs) noexcept { return rhs <= lhs; }
281
282inline int QStringRef::compare(const QString &s, Qt::CaseSensitivity cs) const noexcept
283{ return QStringRef::compare_helper(data1: constData(), length1: length(), data2: s.constData(), length2: s.size(), cs); }
284inline int QStringRef::compare(const QStringRef &s, Qt::CaseSensitivity cs) const noexcept
285{ return QStringRef::compare_helper(data1: constData(), length1: length(), data2: s.constData(), length2: s.length(), cs); }
286inline int QStringRef::compare(QLatin1String s, Qt::CaseSensitivity cs) const noexcept
287{ return QStringRef::compare_helper(data1: constData(), length1: length(), s2: s, cs); }
288inline int QStringRef::compare(const QStringRef &s1, const QString &s2, Qt::CaseSensitivity cs) noexcept
289{ return QStringRef::compare_helper(data1: s1.constData(), length1: s1.length(), data2: s2.constData(), length2: s2.size(), cs); }
290inline int QStringRef::compare(const QStringRef &s1, const QStringRef &s2, Qt::CaseSensitivity cs) noexcept
291{ return QStringRef::compare_helper(data1: s1.constData(), length1: s1.length(), data2: s2.constData(), length2: s2.length(), cs); }
292inline int QStringRef::compare(const QStringRef &s1, QLatin1String s2, Qt::CaseSensitivity cs) noexcept
293{ return QStringRef::compare_helper(data1: s1.constData(), length1: s1.length(), s2, cs); }
294
295// QLatin1String <> QStringRef
296Q_CORE5COMPAT_EXPORT bool operator==(QLatin1String lhs, const QStringRef &rhs) noexcept;
297inline bool operator!=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(s: lhs) != 0; }
298inline bool operator< (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(s: lhs) > 0; }
299inline bool operator> (QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(s: lhs) < 0; }
300inline bool operator<=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(s: lhs) >= 0; }
301inline bool operator>=(QLatin1String lhs, const QStringRef &rhs) noexcept { return rhs.compare(s: lhs) <= 0; }
302
303inline bool operator==(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs == lhs; }
304inline bool operator!=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs != lhs; }
305inline bool operator< (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs > lhs; }
306inline bool operator> (const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs < lhs; }
307inline bool operator<=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs >= lhs; }
308inline bool operator>=(const QStringRef &lhs, QLatin1String rhs) noexcept { return rhs <= lhs; }
309
310// QChar <> QStringRef
311inline bool operator==(QChar lhs, const QStringRef &rhs) noexcept
312{ return rhs.size() == 1 && lhs == rhs.front(); }
313inline bool operator< (QChar lhs, const QStringRef &rhs) noexcept
314{ return QStringRef::compare_helper(data1: &lhs, length1: 1, data2: rhs.data(), length2: rhs.size()) < 0; }
315inline bool operator> (QChar lhs, const QStringRef &rhs) noexcept
316{ return QStringRef::compare_helper(data1: &lhs, length1: 1, data2: rhs.data(), length2: rhs.size()) > 0; }
317
318inline bool operator!=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs == rhs); }
319inline bool operator<=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs > rhs); }
320inline bool operator>=(QChar lhs, const QStringRef &rhs) noexcept { return !(lhs < rhs); }
321
322inline bool operator==(const QStringRef &lhs, QChar rhs) noexcept { return rhs == lhs; }
323inline bool operator!=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs == lhs); }
324inline bool operator< (const QStringRef &lhs, QChar rhs) noexcept { return rhs > lhs; }
325inline bool operator> (const QStringRef &lhs, QChar rhs) noexcept { return rhs < lhs; }
326inline bool operator<=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs < lhs); }
327inline bool operator>=(const QStringRef &lhs, QChar rhs) noexcept { return !(rhs > lhs); }
328
329#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
330// QStringRef <> QByteArray
331QT_ASCII_CAST_WARN inline bool operator==(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(s: rhs) == 0; }
332QT_ASCII_CAST_WARN inline bool operator!=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(s: rhs) != 0; }
333QT_ASCII_CAST_WARN inline bool operator< (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(s: rhs) < 0; }
334QT_ASCII_CAST_WARN inline bool operator> (const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(s: rhs) > 0; }
335QT_ASCII_CAST_WARN inline bool operator<=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(s: rhs) <= 0; }
336QT_ASCII_CAST_WARN inline bool operator>=(const QStringRef &lhs, const QByteArray &rhs) { return lhs.compare(s: rhs) >= 0; }
337
338QT_ASCII_CAST_WARN inline bool operator==(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(s: lhs) == 0; }
339QT_ASCII_CAST_WARN inline bool operator!=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(s: lhs) != 0; }
340QT_ASCII_CAST_WARN inline bool operator< (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(s: lhs) > 0; }
341QT_ASCII_CAST_WARN inline bool operator> (const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(s: lhs) < 0; }
342QT_ASCII_CAST_WARN inline bool operator<=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(s: lhs) >= 0; }
343QT_ASCII_CAST_WARN inline bool operator>=(const QByteArray &lhs, const QStringRef &rhs) { return rhs.compare(s: lhs) <= 0; }
344
345// QStringRef <> const char *
346QT_ASCII_CAST_WARN inline bool QStringRef::operator==(const char *s) const
347{ return QStringRef::compare_helper(data1: constData(), length1: size(), data2: s, length2: -1) == 0; }
348QT_ASCII_CAST_WARN inline bool QStringRef::operator!=(const char *s) const
349{ return QStringRef::compare_helper(data1: constData(), length1: size(), data2: s, length2: -1) != 0; }
350QT_ASCII_CAST_WARN inline bool QStringRef::operator<(const char *s) const
351{ return QStringRef::compare_helper(data1: constData(), length1: size(), data2: s, length2: -1) < 0; }
352QT_ASCII_CAST_WARN inline bool QStringRef::operator<=(const char *s) const
353{ return QStringRef::compare_helper(data1: constData(), length1: size(), data2: s, length2: -1) <= 0; }
354QT_ASCII_CAST_WARN inline bool QStringRef::operator>(const char *s) const
355{ return QStringRef::compare_helper(data1: constData(), length1: size(), data2: s, length2: -1) > 0; }
356QT_ASCII_CAST_WARN inline bool QStringRef::operator>=(const char *s) const
357{ return QStringRef::compare_helper(data1: constData(), length1: size(), data2: s, length2: -1) >= 0; }
358
359QT_ASCII_CAST_WARN inline bool operator==(const char *s1, const QStringRef &s2)
360{ return QStringRef::compare_helper(data1: s2.constData(), length1: s2.size(), data2: s1, length2: -1) == 0; }
361QT_ASCII_CAST_WARN inline bool operator!=(const char *s1, const QStringRef &s2)
362{ return QStringRef::compare_helper(data1: s2.constData(), length1: s2.size(), data2: s1, length2: -1) != 0; }
363QT_ASCII_CAST_WARN inline bool operator<(const char *s1, const QStringRef &s2)
364{ return QStringRef::compare_helper(data1: s2.constData(), length1: s2.size(), data2: s1, length2: -1) > 0; }
365QT_ASCII_CAST_WARN inline bool operator<=(const char *s1, const QStringRef &s2)
366{ return QStringRef::compare_helper(data1: s2.constData(), length1: s2.size(), data2: s1, length2: -1) >= 0; }
367QT_ASCII_CAST_WARN inline bool operator>(const char *s1, const QStringRef &s2)
368{ return QStringRef::compare_helper(data1: s2.constData(), length1: s2.size(), data2: s1, length2: -1) < 0; }
369QT_ASCII_CAST_WARN inline bool operator>=(const char *s1, const QStringRef &s2)
370{ return QStringRef::compare_helper(data1: s2.constData(), length1: s2.size(), data2: s1, length2: -1) <= 0; }
371#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
372
373inline int QStringRef::localeAwareCompare(const QString &s) const
374{ return QString::localeAwareCompare(s1: QStringView{ *this }, s2: QStringView{ s }); }
375inline int QStringRef::localeAwareCompare(const QStringRef &s) const
376{ return QString::localeAwareCompare(s1: QStringView{ *this }, s2: QStringView{ s }); }
377inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QString &s2)
378{ return QString::localeAwareCompare(s1: QStringView{ s1 }, s2: QStringView{ s2 }); }
379inline int QStringRef::localeAwareCompare(const QStringRef &s1, const QStringRef &s2)
380{ return QString::localeAwareCompare(s1: QStringView{ s1 }, s2: QStringView{ s2 }); }
381
382inline bool QStringRef::contains(const QString &s, Qt::CaseSensitivity cs) const
383{ return indexOf(str: s, from: 0, cs) != -1; }
384inline bool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
385{ return indexOf(str: s, from: 0, cs) != -1; }
386inline bool QStringRef::contains(QLatin1String s, Qt::CaseSensitivity cs) const
387{ return indexOf(str: s, from: 0, cs) != -1; }
388inline bool QStringRef::contains(QChar c, Qt::CaseSensitivity cs) const
389{ return indexOf(ch: c, from: 0, cs) != -1; }
390inline bool QStringRef::contains(QStringView s, Qt::CaseSensitivity cs) const noexcept
391{ return indexOf(s, from: 0, cs) != -1; }
392
393#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER)
394inline QString operator+(const QString &s1, const QStringRef &s2)
395{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
396inline QString operator+(const QStringRef &s1, const QString &s2)
397{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
398inline QString operator+(const QStringRef &s1, QLatin1String s2)
399{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
400inline QString operator+(QLatin1String s1, const QStringRef &s2)
401{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
402inline QString operator+(const QStringRef &s1, const QStringRef &s2)
403{ QString t; t.reserve(s1.size() + s2.size()); t += s1; t += s2; return t; }
404inline QString operator+(const QStringRef &s1, QChar s2)
405{ QString t; t.reserve(s1.size() + 1); t += s1; t += s2; return t; }
406inline QString operator+(QChar s1, const QStringRef &s2)
407{ QString t; t.reserve(1 + s2.size()); t += s1; t += s2; return t; }
408#endif // !(QT_USE_FAST_OPERATOR_PLUS || QT_USE_QSTRINGBUILDER)
409
410QT_END_NAMESPACE
411
412#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER)
413
414#include <QtCore/qstringbuilder.h>
415
416QT_BEGIN_NAMESPACE
417
418template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
419{
420 typedef QStringRef type;
421 typedef QString ConvertTo;
422 enum { ExactSize = true };
423 static int size(const QStringRef &a) { return a.size(); }
424 static inline void appendTo(const QStringRef &a, QChar *&out)
425 {
426 const int n = a.size();
427 if (n)
428 memcpy(dest: out, src: reinterpret_cast<const char*>(a.constData()), n: sizeof(QChar) * n);
429 out += n;
430 }
431};
432
433QT_END_NAMESPACE
434
435#endif
436
437#endif // QSTRINGREF_H
438

source code of qt5compat/src/core5/text/qstringref.h