1/****************************************************************************
2**
3** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
4** Copyright (C) 2019 Mail.ru Group.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the test suite of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#undef QT_NO_CAST_FROM_ASCII
31#undef QT_NO_CAST_TO_ASCII
32#undef QT_ASCII_CAST_WARNINGS
33
34#include <QString>
35#include <QStringView>
36#include <QChar>
37#include <QScopedArrayPointer>
38#include <QStringRef>
39#include <QLatin1String>
40#include <QVector>
41
42#include <QTest>
43
44Q_DECLARE_METATYPE(QLatin1String)
45Q_DECLARE_METATYPE(QStringRef)
46
47template <typename T>
48QString toQString(const T &t) { return QString(t); }
49QString toQString(const QStringRef &ref) { return ref.toString(); }
50QString toQString(QStringView view) { return view.toString(); }
51
52template <typename Iterable>
53QStringList toQStringList(const Iterable &i) {
54 QStringList result;
55 for (auto &e : i)
56 result.push_back(t: toQString(e));
57 return result;
58}
59
60// FIXME: these are missing at the time of writing, add them, then remove the dummies here:
61#define MAKE_RELOP(op, A1, A2) \
62 static bool operator op (A1 lhs, A2 rhs) \
63 { return toQString(lhs) op toQString(rhs); } \
64 /*end*/
65#define MAKE_ALL(A1, A2) \
66 MAKE_RELOP(==, A1, A2) \
67 MAKE_RELOP(!=, A1, A2) \
68 MAKE_RELOP(<, A1, A2) \
69 MAKE_RELOP(>, A1, A2) \
70 MAKE_RELOP(<=, A1, A2) \
71 MAKE_RELOP(>=, A1, A2) \
72 /*end*/
73
74MAKE_ALL(QByteArray, QChar)
75MAKE_ALL(QByteArray, QLatin1String)
76MAKE_ALL(QByteArray, char16_t)
77MAKE_ALL(char16_t, QByteArray)
78
79MAKE_ALL(const char*, QChar)
80
81#undef MAKE_ALL
82#undef MAKE_RELOP
83// END FIXME
84
85static Q_DECL_CONSTEXPR int sign(int i) noexcept
86{
87 return i < 0 ? -1 :
88 i > 0 ? +1 :
89 /*else*/ 0 ;
90}
91
92// Return a plain ASCII row name consisting of maximum 16 chars and the
93// size for data
94static QByteArray rowName(const QByteArray &data)
95{
96 const int size = data.size();
97 QScopedArrayPointer<char> prettyC(QTest::toPrettyCString(unicode: data.constData(), length: qMin(a: 16, b: size)));
98 QByteArray result = prettyC.data();
99 result += " (";
100 result += QByteArray::number(size);
101 result += ')';
102 return result;
103}
104
105# define QVERIFY_NOEXCEPT(expr) do { \
106 if (!has_nothrow_compare<LHS, RHS>::value) \
107 QEXPECT_FAIL("", "Qt is missing a nothrow utf8-utf16 comparator", Continue); \
108 QVERIFY(noexcept(expr)); } while (0)
109
110class tst_QStringApiSymmetry : public QObject
111{
112 Q_OBJECT
113
114 //
115 // Mixed UTF-16, UTF-8, Latin-1 checks:
116 //
117
118 void compare_data(bool hasConceptOfNullAndEmpty=true);
119 template <typename LHS, typename RHS>
120 void compare_impl() const;
121
122private Q_SLOTS:
123 // test all combinations of {QChar, char16_t, QStringRef, QString, QStringView, QLatin1String, QByteArray, const char*}
124 void compare_QChar_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
125 void compare_QChar_QChar() { compare_impl<QChar, QChar>(); }
126 void compare_QChar_char16_t_data() { compare_data(hasConceptOfNullAndEmpty: false); }
127 void compare_QChar_char16_t() { compare_impl<QChar, char16_t>(); }
128 void compare_QChar_QStringRef_data() { compare_data(hasConceptOfNullAndEmpty: false); }
129 void compare_QChar_QStringRef() { compare_impl<QChar, QStringRef>(); }
130 void compare_QChar_QString_data() { compare_data(hasConceptOfNullAndEmpty: false); }
131 void compare_QChar_QString() { compare_impl<QChar, QString>(); }
132 void compare_QChar_QStringView_data() { compare_data(hasConceptOfNullAndEmpty: false); }
133 void compare_QChar_QStringView() { compare_impl<QChar, QStringView>(); }
134 void compare_QChar_QLatin1String_data() { compare_data(hasConceptOfNullAndEmpty: false); }
135 void compare_QChar_QLatin1String() { compare_impl<QChar, QLatin1String>(); }
136 void compare_QChar_QByteArray_data() { compare_data(hasConceptOfNullAndEmpty: false); }
137 void compare_QChar_QByteArray() { compare_impl<QChar, QByteArray>(); }
138 void compare_QChar_const_char_star_data() { compare_data(hasConceptOfNullAndEmpty: false); }
139 void compare_QChar_const_char_star() { compare_impl<QChar, const char *>(); }
140
141 void compare_char16_t_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
142 void compare_char16_t_QChar() { compare_impl<char16_t, QChar>(); }
143 //void compare_char16_t_char16_t_data() { compare_data(false); }
144 //void compare_char16_t_char16_t() { compare_impl<char16_t, char16_t>(); }
145 void compare_char16_t_QStringRef_data() { compare_data(hasConceptOfNullAndEmpty: false); }
146 void compare_char16_t_QStringRef() { compare_impl<char16_t, QStringRef>(); }
147 void compare_char16_t_QString_data() { compare_data(hasConceptOfNullAndEmpty: false); }
148 void compare_char16_t_QString() { compare_impl<char16_t, QString>(); }
149 void compare_char16_t_QStringView_data() { compare_data(hasConceptOfNullAndEmpty: false); }
150 void compare_char16_t_QStringView() { compare_impl<char16_t, QStringView>(); }
151 void compare_char16_t_QLatin1String_data() { compare_data(hasConceptOfNullAndEmpty: false); }
152 void compare_char16_t_QLatin1String() { compare_impl<char16_t, QLatin1String>(); }
153 void compare_char16_t_QByteArray_data() { compare_data(hasConceptOfNullAndEmpty: false); }
154 void compare_char16_t_QByteArray() { compare_impl<char16_t, QByteArray>(); }
155 //void compare_char16_t_const_char_star_data() { compare_data(false); }
156 //void compare_char16_t_const_char_star() { compare_impl<char16_t, const char *>(); }
157
158 void compare_QStringRef_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
159 void compare_QStringRef_QChar() { compare_impl<QStringRef, QChar>(); }
160 void compare_QStringRef_char16_t_data() { compare_data(hasConceptOfNullAndEmpty: false); }
161 void compare_QStringRef_char16_t() { compare_impl<QStringRef, char16_t>(); }
162 void compare_QStringRef_QStringRef_data() { compare_data(); }
163 void compare_QStringRef_QStringRef() { compare_impl<QStringRef, QStringRef>(); }
164 void compare_QStringRef_QString_data() { compare_data(); }
165 void compare_QStringRef_QString() { compare_impl<QStringRef, QString>(); }
166 void compare_QStringRef_QStringView_data() { compare_data(); }
167 void compare_QStringRef_QStringView() { compare_impl<QStringRef, QStringView>(); }
168 void compare_QStringRef_QLatin1String_data() { compare_data(); }
169 void compare_QStringRef_QLatin1String() { compare_impl<QStringRef, QLatin1String>(); }
170 void compare_QStringRef_QByteArray_data() { compare_data(); }
171 void compare_QStringRef_QByteArray() { compare_impl<QStringRef, QByteArray>(); }
172 void compare_QStringRef_const_char_star_data() { compare_data(); }
173 void compare_QStringRef_const_char_star() { compare_impl<QStringRef, const char *>(); }
174
175 void compare_QString_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
176 void compare_QString_QChar() { compare_impl<QString, QChar>(); }
177 void compare_QString_char16_t_data() { compare_data(hasConceptOfNullAndEmpty: false); }
178 void compare_QString_char16_t() { compare_impl<QString, char16_t>(); }
179 void compare_QString_QStringRef_data() { compare_data(); }
180 void compare_QString_QStringRef() { compare_impl<QString, QStringRef>(); }
181 void compare_QString_QString_data() { compare_data(); }
182 void compare_QString_QString() { compare_impl<QString, QString>(); }
183 void compare_QString_QStringView_data() { compare_data(); }
184 void compare_QString_QStringView() { compare_impl<QString, QStringView>(); }
185 void compare_QString_QLatin1String_data() { compare_data(); }
186 void compare_QString_QLatin1String() { compare_impl<QString, QLatin1String>(); }
187 void compare_QString_QByteArray_data() { compare_data(); }
188 void compare_QString_QByteArray() { compare_impl<QString, QByteArray>(); }
189 void compare_QString_const_char_star_data() { compare_data(); }
190 void compare_QString_const_char_star() { compare_impl<QString, const char *>(); }
191
192 void compare_QStringView_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
193 void compare_QStringView_QChar() { compare_impl<QStringView, QChar>(); }
194 void compare_QStringView_char16_t_data() { compare_data(hasConceptOfNullAndEmpty: false); }
195 void compare_QStringView_char16_t() { compare_impl<QStringView, char16_t>(); }
196 void compare_QStringView_QStringRef_data() { compare_data(); }
197 void compare_QStringView_QStringRef() { compare_impl<QStringView, QStringRef>(); }
198 void compare_QStringView_QString_data() { compare_data(); }
199 void compare_QStringView_QString() { compare_impl<QStringView, QString>(); }
200 void compare_QStringView_QStringView_data() { compare_data(); }
201 void compare_QStringView_QStringView() { compare_impl<QStringView, QStringView>(); }
202 void compare_QStringView_QLatin1String_data() { compare_data(); }
203 void compare_QStringView_QLatin1String() { compare_impl<QStringView, QLatin1String>(); }
204#ifdef NOT_YET_IMPLMENTED
205 void compare_QStringView_QByteArray_data() { compare_data(); }
206 void compare_QStringView_QByteArray() { compare_impl<QStringView, QByteArray>(); }
207 void compare_QStringView_const_char_star_data() { compare_data(); }
208 void compare_QStringView_const_char_star() { compare_impl<QStringView, const char *>(); }
209#endif
210
211 void compare_QLatin1String_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
212 void compare_QLatin1String_QChar() { compare_impl<QLatin1String, QChar>(); }
213 void compare_QLatin1String_char16_t_data() { compare_data(hasConceptOfNullAndEmpty: false); }
214 void compare_QLatin1String_char16_t() { compare_impl<QLatin1String, char16_t>(); }
215 void compare_QLatin1String_QStringRef_data() { compare_data(); }
216 void compare_QLatin1String_QStringRef() { compare_impl<QLatin1String, QStringRef>(); }
217 void compare_QLatin1String_QString_data() { compare_data(); }
218 void compare_QLatin1String_QString() { compare_impl<QLatin1String, QString>(); }
219 void compare_QLatin1String_QStringView_data() { compare_data(); }
220 void compare_QLatin1String_QStringView() { compare_impl<QLatin1String, QStringView>(); }
221 void compare_QLatin1String_QLatin1String_data() { compare_data(); }
222 void compare_QLatin1String_QLatin1String() { compare_impl<QLatin1String, QLatin1String>(); }
223 void compare_QLatin1String_QByteArray_data() { compare_data(); }
224 void compare_QLatin1String_QByteArray() { compare_impl<QLatin1String, QByteArray>(); }
225 void compare_QLatin1String_const_char_star_data() { compare_data(); }
226 void compare_QLatin1String_const_char_star() { compare_impl<QLatin1String, const char *>(); }
227
228 void compare_QByteArray_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
229 void compare_QByteArray_QChar() { compare_impl<QByteArray, QChar>(); }
230 void compare_QByteArray_char16_t_data() { compare_data(hasConceptOfNullAndEmpty: false); }
231 void compare_QByteArray_char16_t() { compare_impl<QByteArray, char16_t>(); }
232 void compare_QByteArray_QStringRef_data() { compare_data(); }
233 void compare_QByteArray_QStringRef() { compare_impl<QByteArray, QStringRef>(); }
234 void compare_QByteArray_QString_data() { compare_data(); }
235 void compare_QByteArray_QString() { compare_impl<QByteArray, QString>(); }
236 void compare_QByteArray_QLatin1String_data() { compare_data(); }
237 void compare_QByteArray_QLatin1String() { compare_impl<QByteArray, QLatin1String>(); }
238 void compare_QByteArray_QByteArray_data() { compare_data(); }
239 void compare_QByteArray_QByteArray() { compare_impl<QByteArray, QByteArray>(); }
240 void compare_QByteArray_const_char_star_data() { compare_data(); }
241 void compare_QByteArray_const_char_star() { compare_impl<QByteArray, const char *>(); }
242
243 void compare_const_char_star_QChar_data() { compare_data(hasConceptOfNullAndEmpty: false); }
244 void compare_const_char_star_QChar() { compare_impl<const char *, QChar>(); }
245 //void compare_const_char_star_char16_t_data() { compare_data(false); }
246 //void compare_const_char_star_char16_t() { compare_impl<const char *, char16_t>(); }
247 void compare_const_char_star_QStringRef_data() { compare_data(); }
248 void compare_const_char_star_QStringRef() { compare_impl<const char *, QStringRef>(); }
249 void compare_const_char_star_QString_data() { compare_data(); }
250 void compare_const_char_star_QString() { compare_impl<const char *, QString>(); }
251 void compare_const_char_star_QLatin1String_data() { compare_data(hasConceptOfNullAndEmpty: false); }
252 void compare_const_char_star_QLatin1String() { compare_impl<const char *, QLatin1String>(); }
253 void compare_const_char_star_QByteArray_data() { compare_data(); }
254 void compare_const_char_star_QByteArray() { compare_impl<const char *, QByteArray>(); }
255 //void compare_const_char_star_const_char_star_data() { compare_data(); }
256 //void compare_const_char_star_const_char_star() { compare_impl<const char *, const char *>(); }
257
258private:
259 void member_compare_data(bool hasConceptOfNullAndEmpty=true) { compare_data(hasConceptOfNullAndEmpty); }
260 template <typename LHS, typename RHS>
261 void member_compare_impl() const;
262
263private Q_SLOTS:
264 // test all combinations of {QChar, char16_t, QStringRef, QString, QStringView, QLatin1String, QByteArray, const char*}
265#ifdef NOT_YET_IMPLEMENTED // probably never will be - what's the point of QChar::compare(QStringView)?
266 void member_compare_QChar_QChar_data() { member_compare_data(false); }
267 void member_compare_QChar_QChar() { member_compare_impl<QChar, QChar>(); }
268 void member_compare_QChar_char16_t_data() { member_compare_data(false); }
269 void member_compare_QChar_char16_t() { member_compare_impl<QChar, char16_t>(); }
270 void member_compare_QChar_QStringRef_data() { member_compare_data(false); }
271 void member_compare_QChar_QStringRef() { member_compare_impl<QChar, QStringRef>(); }
272 void member_compare_QChar_QString_data() { member_compare_data(false); }
273 void member_compare_QChar_QString() { member_compare_impl<QChar, QString>(); }
274 void member_compare_QChar_QStringView_data() { member_compare_data(false); }
275 void member_compare_QChar_QStringView() { member_compare_impl<QChar, QStringView>(); }
276 void member_compare_QChar_QLatin1String_data() { member_compare_data(false); }
277 void member_compare_QChar_QLatin1String() { member_compare_impl<QChar, QLatin1String>(); }
278 void member_compare_QChar_QByteArray_data() { member_compare_data(false); }
279 void member_compare_QChar_QByteArray() { member_compare_impl<QChar, QByteArray>(); }
280 void member_compare_QChar_const_char_star_data() { member_compare_data(false); }
281 void member_compare_QChar_const_char_star() { member_compare_impl<QChar, const char *>(); }
282#endif
283
284 // void member_compare_char16_t_XXX() - not possible
285
286 void member_compare_QStringRef_QChar_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
287 void member_compare_QStringRef_QChar() { member_compare_impl<QStringRef, QChar>(); }
288 void member_compare_QStringRef_char16_t_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
289 void member_compare_QStringRef_char16_t() { member_compare_impl<QStringRef, char16_t>(); }
290 void member_compare_QStringRef_QStringRef_data() { member_compare_data(); }
291 void member_compare_QStringRef_QStringRef() { member_compare_impl<QStringRef, QStringRef>(); }
292 void member_compare_QStringRef_QString_data() { member_compare_data(); }
293 void member_compare_QStringRef_QString() { member_compare_impl<QStringRef, QString>(); }
294#ifdef NOT_YET_IMPLEMENTED
295 void member_compare_QStringRef_QStringView_data() { member_compare_data(); }
296 void member_compare_QStringRef_QStringView() { member_compare_impl<QStringRef, QStringView>(); }
297#endif
298 void member_compare_QStringRef_QLatin1String_data() { member_compare_data(); }
299 void member_compare_QStringRef_QLatin1String() { member_compare_impl<QStringRef, QLatin1String>(); }
300 void member_compare_QStringRef_QByteArray_data() { member_compare_data(); }
301 void member_compare_QStringRef_QByteArray() { member_compare_impl<QStringRef, QByteArray>(); }
302#ifdef NOT_YET_IMPLEMENTED
303 void member_compare_QStringRef_const_char_star_data() { member_compare_data(); }
304 void member_compare_QStringRef_const_char_star() { member_compare_impl<QStringRef, const char *>(); }
305#endif
306
307 void member_compare_QString_QChar_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
308 void member_compare_QString_QChar() { member_compare_impl<QString, QChar>(); }
309 void member_compare_QString_char16_t_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
310 void member_compare_QString_char16_t() { member_compare_impl<QString, char16_t>(); }
311 void member_compare_QString_QStringRef_data() { member_compare_data(); }
312 void member_compare_QString_QStringRef() { member_compare_impl<QString, QStringRef>(); }
313 void member_compare_QString_QString_data() { member_compare_data(); }
314 void member_compare_QString_QString() { member_compare_impl<QString, QString>(); }
315 void member_compare_QString_QStringView_data() { member_compare_data(); }
316 void member_compare_QString_QStringView() { member_compare_impl<QString, QStringView>(); }
317 void member_compare_QString_QLatin1String_data() { member_compare_data(); }
318 void member_compare_QString_QLatin1String() { member_compare_impl<QString, QLatin1String>(); }
319 void member_compare_QString_QByteArray_data() { member_compare_data(); }
320 void member_compare_QString_QByteArray() { member_compare_impl<QString, QByteArray>(); }
321 void member_compare_QString_const_char_star_data() { member_compare_data(); }
322 void member_compare_QString_const_char_star() { member_compare_impl<QString, const char *>(); }
323
324 void member_compare_QStringView_QChar_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
325 void member_compare_QStringView_QChar() { member_compare_impl<QStringView, QChar>(); }
326 void member_compare_QStringView_char16_t_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
327 void member_compare_QStringView_char16_t() { member_compare_impl<QStringView, char16_t>(); }
328 void member_compare_QStringView_QStringRef_data() { member_compare_data(); }
329 void member_compare_QStringView_QStringRef() { member_compare_impl<QStringView, QStringRef>(); }
330 void member_compare_QStringView_QString_data() { member_compare_data(); }
331 void member_compare_QStringView_QString() { member_compare_impl<QStringView, QString>(); }
332 void member_compare_QStringView_QStringView_data() { member_compare_data(); }
333 void member_compare_QStringView_QStringView() { member_compare_impl<QStringView, QStringView>(); }
334 void member_compare_QStringView_QLatin1String_data() { member_compare_data(); }
335 void member_compare_QStringView_QLatin1String() { member_compare_impl<QStringView, QLatin1String>(); }
336#ifdef NOT_YET_IMPLEMENTED
337 void member_compare_QStringView_QByteArray_data() { member_compare_data(); }
338 void member_compare_QStringView_QByteArray() { member_compare_impl<QStringView, QByteArray>(); }
339 void member_compare_QStringView_const_char_star_data() { member_compare_data(); }
340 void member_compare_QStringView_const_char_star() { member_compare_impl<QStringView, const char *>(); }
341#endif
342
343 void member_compare_QLatin1String_QChar_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
344 void member_compare_QLatin1String_QChar() { member_compare_impl<QLatin1String, QChar>(); }
345 void member_compare_QLatin1String_char16_t_data() { member_compare_data(hasConceptOfNullAndEmpty: false); }
346 void member_compare_QLatin1String_char16_t() { member_compare_impl<QLatin1String, char16_t>(); }
347 void member_compare_QLatin1String_QStringRef_data() { member_compare_data(); }
348 void member_compare_QLatin1String_QStringRef() { member_compare_impl<QLatin1String, QStringRef>(); }
349 void member_compare_QLatin1String_QString_data() { member_compare_data(); }
350 void member_compare_QLatin1String_QString() { member_compare_impl<QLatin1String, QString>(); }
351 void member_compare_QLatin1String_QStringView_data() { member_compare_data(); }
352 void member_compare_QLatin1String_QStringView() { member_compare_impl<QLatin1String, QStringView>(); }
353 void member_compare_QLatin1String_QLatin1String_data() { member_compare_data(); }
354 void member_compare_QLatin1String_QLatin1String() { member_compare_impl<QLatin1String, QLatin1String>(); }
355#ifdef NOT_YET_IMPLEMENTED
356 void member_compare_QLatin1String_QByteArray_data() { member_compare_data(); }
357 void member_compare_QLatin1String_QByteArray() { member_compare_impl<QLatin1String, QByteArray>(); }
358 void member_compare_QLatin1String_const_char_star_data() { member_compare_data(); }
359 void member_compare_QLatin1String_const_char_star() { member_compare_impl<QLatin1String, const char *>(); }
360
361 void member_compare_QByteArray_QChar_data() { member_compare_data(false); }
362 void member_compare_QByteArray_QChar() { member_compare_impl<QByteArray, QChar>(); }
363 void member_compare_QByteArray_char16_t_data() { member_compare_data(false); }
364 void member_compare_QByteArray_char16_t() { member_compare_impl<QByteArray, char16_t>(); }
365 void member_compare_QByteArray_QStringRef_data() { member_compare_data(); }
366 void member_compare_QByteArray_QStringRef() { member_compare_impl<QByteArray, QStringRef>(); }
367 void member_compare_QByteArray_QString_data() { member_compare_data(); }
368 void member_compare_QByteArray_QString() { member_compare_impl<QByteArray, QString>(); }
369 void member_compare_QByteArray_QLatin1String_data() { member_compare_data(); }
370 void member_compare_QByteArray_QLatin1String() { member_compare_impl<QByteArray, QLatin1String>(); }
371#endif
372 void member_compare_QByteArray_QByteArray_data() { member_compare_data(); }
373 void member_compare_QByteArray_QByteArray() { member_compare_impl<QByteArray, QByteArray>(); }
374 void member_compare_QByteArray_const_char_star_data() { member_compare_data(); }
375 void member_compare_QByteArray_const_char_star() { member_compare_impl<QByteArray, const char *>(); }
376
377private:
378 void startsWith_data(bool rhsIsQChar = false);
379 template <typename Haystack, typename Needle> void startsWith_impl() const;
380
381 void endsWith_data(bool rhsIsQChar = false);
382 template <typename Haystack, typename Needle> void endsWith_impl() const;
383
384private Q_SLOTS:
385 // test all combinations of {QString, QStringRef, QStringView, QLatin1String} x {QString, QStringRef, QStringView, QLatin1String, QChar, char16_t}:
386 void startsWith_QString_QString_data() { startsWith_data(); }
387 void startsWith_QString_QString() { startsWith_impl<QString, QString>(); }
388 void startsWith_QString_QStringRef_data() { startsWith_data(); }
389 void startsWith_QString_QStringRef() { startsWith_impl<QString, QStringRef>(); }
390 void startsWith_QString_QStringView_data() { startsWith_data(); }
391 void startsWith_QString_QStringView() { startsWith_impl<QString, QStringView>(); }
392 void startsWith_QString_QLatin1String_data() { startsWith_data(); }
393 void startsWith_QString_QLatin1String() { startsWith_impl<QString, QLatin1String>(); }
394 void startsWith_QString_QChar_data() { startsWith_data(rhsIsQChar: false); }
395 void startsWith_QString_QChar() { startsWith_impl<QString, QChar>(); }
396 void startsWith_QString_char16_t_data() { startsWith_data(rhsIsQChar: false); }
397 void startsWith_QString_char16_t() { startsWith_impl<QString, char16_t>(); }
398
399 void startsWith_QStringRef_QString_data() { startsWith_data(); }
400 void startsWith_QStringRef_QString() { startsWith_impl<QStringRef, QString>(); }
401 void startsWith_QStringRef_QStringRef_data() { startsWith_data(); }
402 void startsWith_QStringRef_QStringRef() { startsWith_impl<QStringRef, QStringRef>(); }
403 void startsWith_QStringRef_QStringView_data() { startsWith_data(); }
404 void startsWith_QStringRef_QStringView() { startsWith_impl<QStringRef, QStringView>(); }
405 void startsWith_QStringRef_QLatin1String_data() { startsWith_data(); }
406 void startsWith_QStringRef_QLatin1String() { startsWith_impl<QStringRef, QLatin1String>(); }
407 void startsWith_QStringRef_QChar_data() { startsWith_data(rhsIsQChar: false); }
408 void startsWith_QStringRef_QChar() { startsWith_impl<QStringRef, QChar>(); }
409 void startsWith_QStringRef_char16_t_data() { startsWith_data(rhsIsQChar: false); }
410 void startsWith_QStringRef_char16_t() { startsWith_impl<QStringRef, char16_t>(); }
411
412 void startsWith_QStringView_QString_data() { startsWith_data(); }
413 void startsWith_QStringView_QString() { startsWith_impl<QStringView, QString>(); }
414 void startsWith_QStringView_QStringRef_data() { startsWith_data(); }
415 void startsWith_QStringView_QStringRef() { startsWith_impl<QStringView, QStringRef>(); }
416 void startsWith_QStringView_QStringView_data() { startsWith_data(); }
417 void startsWith_QStringView_QStringView() { startsWith_impl<QStringView, QStringView>(); }
418 void startsWith_QStringView_QLatin1String_data() { startsWith_data(); }
419 void startsWith_QStringView_QLatin1String() { startsWith_impl<QStringView, QLatin1String>(); }
420 void startsWith_QStringView_QChar_data() { startsWith_data(rhsIsQChar: false); }
421 void startsWith_QStringView_QChar() { startsWith_impl<QStringView, QChar>(); }
422 void startsWith_QStringView_char16_t_data() { startsWith_data(rhsIsQChar: false); }
423 void startsWith_QStringView_char16_t() { startsWith_impl<QStringView, char16_t>(); }
424
425 void startsWith_QLatin1String_QString_data() { startsWith_data(); }
426 void startsWith_QLatin1String_QString() { startsWith_impl<QLatin1String, QString>(); }
427 void startsWith_QLatin1String_QStringRef_data() { startsWith_data(); }
428 void startsWith_QLatin1String_QStringRef() { startsWith_impl<QLatin1String, QStringRef>(); }
429 void startsWith_QLatin1String_QStringView_data() { startsWith_data(); }
430 void startsWith_QLatin1String_QStringView() { startsWith_impl<QLatin1String, QStringView>(); }
431 void startsWith_QLatin1String_QLatin1String_data() { startsWith_data(); }
432 void startsWith_QLatin1String_QLatin1String() { startsWith_impl<QLatin1String, QLatin1String>(); }
433 void startsWith_QLatin1String_QChar_data() { startsWith_data(rhsIsQChar: false); }
434 void startsWith_QLatin1String_QChar() { startsWith_impl<QLatin1String, QChar>(); }
435 void startsWith_QLatin1String_char16_t_data() { startsWith_data(rhsIsQChar: false); }
436 void startsWith_QLatin1String_char16_t() { startsWith_impl<QLatin1String, char16_t>(); }
437
438 void endsWith_QString_QString_data() { endsWith_data(); }
439 void endsWith_QString_QString() { endsWith_impl<QString, QString>(); }
440 void endsWith_QString_QStringRef_data() { endsWith_data(); }
441 void endsWith_QString_QStringRef() { endsWith_impl<QString, QStringRef>(); }
442 void endsWith_QString_QStringView_data() { endsWith_data(); }
443 void endsWith_QString_QStringView() { endsWith_impl<QString, QStringView>(); }
444 void endsWith_QString_QLatin1String_data() { endsWith_data(); }
445 void endsWith_QString_QLatin1String() { endsWith_impl<QString, QLatin1String>(); }
446 void endsWith_QString_QChar_data() { endsWith_data(rhsIsQChar: false); }
447 void endsWith_QString_QChar() { endsWith_impl<QString, QChar>(); }
448 void endsWith_QString_char16_t_data() { endsWith_data(rhsIsQChar: false); }
449 void endsWith_QString_char16_t() { endsWith_impl<QString, char16_t>(); }
450
451 void endsWith_QStringRef_QString_data() { endsWith_data(); }
452 void endsWith_QStringRef_QString() { endsWith_impl<QStringRef, QString>(); }
453 void endsWith_QStringRef_QStringRef_data() { endsWith_data(); }
454 void endsWith_QStringRef_QStringRef() { endsWith_impl<QStringRef, QStringRef>(); }
455 void endsWith_QStringRef_QStringView_data() { endsWith_data(); }
456 void endsWith_QStringRef_QStringView() { endsWith_impl<QStringRef, QStringView>(); }
457 void endsWith_QStringRef_QLatin1String_data() { endsWith_data(); }
458 void endsWith_QStringRef_QLatin1String() { endsWith_impl<QStringRef, QLatin1String>(); }
459 void endsWith_QStringRef_QChar_data() { endsWith_data(rhsIsQChar: false); }
460 void endsWith_QStringRef_QChar() { endsWith_impl<QStringRef, QChar>(); }
461 void endsWith_QStringRef_char16_t_data() { endsWith_data(rhsIsQChar: false); }
462 void endsWith_QStringRef_char16_t() { endsWith_impl<QStringRef, char16_t>(); }
463
464 void endsWith_QStringView_QString_data() { endsWith_data(); }
465 void endsWith_QStringView_QString() { endsWith_impl<QStringView, QString>(); }
466 void endsWith_QStringView_QStringRef_data() { endsWith_data(); }
467 void endsWith_QStringView_QStringRef() { endsWith_impl<QStringView, QStringRef>(); }
468 void endsWith_QStringView_QStringView_data() { endsWith_data(); }
469 void endsWith_QStringView_QStringView() { endsWith_impl<QStringView, QStringView>(); }
470 void endsWith_QStringView_QLatin1String_data() { endsWith_data(); }
471 void endsWith_QStringView_QLatin1String() { endsWith_impl<QStringView, QLatin1String>(); }
472 void endsWith_QStringView_QChar_data() { endsWith_data(rhsIsQChar: false); }
473 void endsWith_QStringView_QChar() { endsWith_impl<QStringView, QChar>(); }
474 void endsWith_QStringView_char16_t_data() { endsWith_data(rhsIsQChar: false); }
475 void endsWith_QStringView_char16_t() { endsWith_impl<QStringView, char16_t>(); }
476
477 void endsWith_QLatin1String_QString_data() { endsWith_data(); }
478 void endsWith_QLatin1String_QString() { endsWith_impl<QLatin1String, QString>(); }
479 void endsWith_QLatin1String_QStringRef_data() { endsWith_data(); }
480 void endsWith_QLatin1String_QStringRef() { endsWith_impl<QLatin1String, QStringRef>(); }
481 void endsWith_QLatin1String_QStringView_data() { endsWith_data(); }
482 void endsWith_QLatin1String_QStringView() { endsWith_impl<QLatin1String, QStringView>(); }
483 void endsWith_QLatin1String_QLatin1String_data() { endsWith_data(); }
484 void endsWith_QLatin1String_QLatin1String() { endsWith_impl<QLatin1String, QLatin1String>(); }
485 void endsWith_QLatin1String_QChar_data() { endsWith_data(rhsIsQChar: false); }
486 void endsWith_QLatin1String_QChar() { endsWith_impl<QLatin1String, QChar>(); }
487 void endsWith_QLatin1String_char16_t_data() { endsWith_data(rhsIsQChar: false); }
488 void endsWith_QLatin1String_char16_t() { endsWith_impl<QLatin1String, char16_t>(); }
489
490private:
491 void split_data(bool rhsHasVariableLength = true);
492 template <typename Haystack, typename Needle> void split_impl() const;
493
494private Q_SLOTS:
495 // test all combinations of {QString, QStringRef} x {QString, QLatin1String, QChar}:
496 void split_QString_QString_data() { split_data(); }
497 void split_QString_QString() { split_impl<QString, QString>(); }
498 void split_QString_QLatin1String_data() { split_data(); }
499 void split_QString_QLatin1String() { split_impl<QString, QLatin1String>(); }
500 void split_QString_QChar_data() { split_data(rhsHasVariableLength: false); }
501 void split_QString_QChar() { split_impl<QString, QChar>(); }
502
503 void split_QStringRef_QString_data() { split_data(); }
504 void split_QStringRef_QString() { split_impl<QStringRef, QString>(); }
505 void split_QStringRef_QLatin1String_data() { split_data(); }
506 void split_QStringRef_QLatin1String() { split_impl<QStringRef, QLatin1String>(); }
507 void split_QStringRef_QChar_data() { split_data(rhsHasVariableLength: false); }
508 void split_QStringRef_QChar() { split_impl<QStringRef, QChar>(); }
509
510 void split_QStringView_QString_data() { split_data(); }
511 void split_QStringView_QString() { split_impl<QStringView, QString>(); }
512 void split_QStringView_QChar_data() { split_data(rhsHasVariableLength: false); }
513 void split_QStringView_QChar() { split_impl<QStringView, QChar>(); }
514
515private:
516 void mid_data();
517 template <typename String> void mid_impl();
518
519 void left_data();
520 template <typename String> void left_impl();
521
522 void right_data();
523 template <typename String> void right_impl();
524
525 void chop_data();
526 template <typename String> void chop_impl();
527
528 void truncate_data() { left_data(); }
529 template <typename String> void truncate_impl();
530
531private Q_SLOTS:
532
533 void mid_QString_data() { mid_data(); }
534 void mid_QString() { mid_impl<QString>(); }
535 void mid_QStringRef_data() { mid_data(); }
536 void mid_QStringRef() { mid_impl<QStringRef>(); }
537 void mid_QStringView_data() { mid_data(); }
538 void mid_QStringView() { mid_impl<QStringView>(); }
539 void mid_QLatin1String_data() { mid_data(); }
540 void mid_QLatin1String() { mid_impl<QLatin1String>(); }
541 void mid_QByteArray_data() { mid_data(); }
542 void mid_QByteArray() { mid_impl<QByteArray>(); }
543
544 void left_truncate_QString_data() { left_data(); }
545 void left_truncate_QString() { left_impl<QString>(); }
546 void left_truncate_QStringRef_data() { left_data(); }
547 void left_truncate_QStringRef() { left_impl<QStringRef>(); }
548 void left_truncate_QStringView_data() { left_data(); }
549 void left_truncate_QStringView() { left_impl<QStringView>(); }
550 void left_truncate_QLatin1String_data() { left_data(); }
551 void left_truncate_QLatin1String() { left_impl<QLatin1String>(); }
552 void left_truncate_QByteArray_data() { left_data(); }
553 void left_truncate_QByteArray() { left_impl<QByteArray>(); }
554
555 void right_QString_data() { right_data(); }
556 void right_QString() { right_impl<QString>(); }
557 void right_QStringRef_data() { right_data(); }
558 void right_QStringRef() { right_impl<QStringRef>(); }
559 void right_QStringView_data() { right_data(); }
560 void right_QStringView() { right_impl<QStringView>(); }
561 void right_QLatin1String_data() { right_data(); }
562 void right_QLatin1String() { right_impl<QLatin1String>(); }
563 void right_QByteArray_data() { right_data(); }
564 void right_QByteArray() { right_impl<QByteArray>(); }
565
566 void chop_QString_data() { chop_data(); }
567 void chop_QString() { chop_impl<QString>(); }
568 void chop_QStringRef_data() { chop_data(); }
569 void chop_QStringRef() { chop_impl<QStringRef>(); }
570 void chop_QStringView_data() { chop_data(); }
571 void chop_QStringView() { chop_impl<QStringView>(); }
572 void chop_QLatin1String_data() { chop_data(); }
573 void chop_QLatin1String() { chop_impl<QLatin1String>(); }
574 void chop_QByteArray_data() { chop_data(); }
575 void chop_QByteArray() { chop_impl<QByteArray>(); }
576
577private:
578 void trimmed_data();
579 template <typename String> void trimmed_impl();
580
581private Q_SLOTS:
582 void trim_trimmed_QString_data() { trimmed_data(); }
583 void trim_trimmed_QString() { trimmed_impl<QString>(); }
584 void trim_trimmed_QStringRef_data() { trimmed_data(); }
585 void trim_trimmed_QStringRef() { trimmed_impl<QStringRef>(); }
586 void trim_trimmed_QStringView_data() { trimmed_data(); }
587 void trim_trimmed_QStringView() { trimmed_impl<QStringView>(); }
588 void trim_trimmed_QLatin1String_data() { trimmed_data(); }
589 void trim_trimmed_QLatin1String() { trimmed_impl<QLatin1String>(); }
590 void trim_trimmed_QByteArray_data() { trimmed_data(); }
591 void trim_trimmed_QByteArray() { trimmed_impl<QByteArray>(); }
592
593 //
594 // UTF-16-only checks:
595 //
596private:
597
598 void toLocal8Bit_data();
599 template <typename String> void toLocal8Bit_impl();
600
601 void toLatin1_data();
602 template <typename String> void toLatin1_impl();
603
604 void toUtf8_data();
605 template <typename String> void toUtf8_impl();
606
607 void toUcs4_data();
608 template <typename String> void toUcs4_impl();
609
610private Q_SLOTS:
611
612 void toLocal8Bit_QString_data() { toLocal8Bit_data(); }
613 void toLocal8Bit_QString() { toLocal8Bit_impl<QString>(); }
614 void toLocal8Bit_QStringRef_data() { toLocal8Bit_data(); }
615 void toLocal8Bit_QStringRef() { toLocal8Bit_impl<QStringRef>(); }
616 void toLocal8Bit_QStringView_data() { toLocal8Bit_data(); }
617 void toLocal8Bit_QStringView() { toLocal8Bit_impl<QStringView>(); }
618
619 void toLatin1_QString_data() { toLatin1_data(); }
620 void toLatin1_QString() { toLatin1_impl<QString>(); }
621 void toLatin1_QStringRef_data() { toLatin1_data(); }
622 void toLatin1_QStringRef() { toLatin1_impl<QStringRef>(); }
623 void toLatin1_QStringView_data() { toLatin1_data(); }
624 void toLatin1_QStringView() { toLatin1_impl<QStringView>(); }
625
626 void toUtf8_QString_data() { toUtf8_data(); }
627 void toUtf8_QString() { toUtf8_impl<QString>(); }
628 void toUtf8_QStringRef_data() { toUtf8_data(); }
629 void toUtf8_QStringRef() { toUtf8_impl<QStringRef>(); }
630 void toUtf8_QStringView_data() { toUtf8_data(); }
631 void toUtf8_QStringView() { toUtf8_impl<QStringView>(); }
632
633 void toUcs4_QString_data() { toUcs4_data(); }
634 void toUcs4_QString() { toUcs4_impl<QString>(); }
635 void toUcs4_QStringRef_data() { toUcs4_data(); }
636 void toUcs4_QStringRef() { toUcs4_impl<QStringRef>(); }
637 void toUcs4_QStringView_data() { toUcs4_data(); }
638 void toUcs4_QStringView() { toUcs4_impl<QStringView>(); }
639
640private:
641 template <typename Haystack, typename Needle> void indexOf_impl() const;
642 void indexOf_data(bool rhsHasVariableLength = true);
643
644private Q_SLOTS:
645 // test all combinations of {QString, QLatin1String, QStringRef, QStringView} x {QString, QLatin1String, QStringRef, QStringView, QChar, char16_t}:
646 void indexOf_QString_QString_data() { indexOf_data(); }
647 void indexOf_QString_QString() { indexOf_impl<QString, QString>(); }
648 void indexOf_QString_QLatin1String_data() { indexOf_data(); }
649 void indexOf_QString_QLatin1String() { indexOf_impl<QString, QLatin1String>(); }
650 void indexOf_QString_QStringRef_data() { indexOf_data(); }
651 void indexOf_QString_QStringRef() { indexOf_impl<QString, QStringRef>(); }
652 void indexOf_QString_QStringView_data() { indexOf_data(); }
653 void indexOf_QString_QStringView() { indexOf_impl<QString, QStringView>(); }
654 void indexOf_QString_QChar_data() { indexOf_data(rhsHasVariableLength: false); }
655 void indexOf_QString_QChar() { indexOf_impl<QString, QChar>(); }
656 void indexOf_QString_char16_t_data() { indexOf_data(rhsHasVariableLength: false); }
657 void indexOf_QString_char16_t() { indexOf_impl<QString, char16_t>(); }
658
659 void indexOf_QLatin1String_QString_data() { indexOf_data(); }
660 void indexOf_QLatin1String_QString() { indexOf_impl<QLatin1String, QString>(); }
661 void indexOf_QLatin1String_QLatin1String_data() { indexOf_data(); }
662 void indexOf_QLatin1String_QLatin1String() { indexOf_impl<QLatin1String, QLatin1String>(); }
663 void indexOf_QLatin1String_QStringRef_data() { indexOf_data(); }
664 void indexOf_QLatin1String_QStringRef() { indexOf_impl<QLatin1String, QStringRef>(); }
665 void indexOf_QLatin1String_QStringView_data() { indexOf_data(); }
666 void indexOf_QLatin1String_QStringView() { indexOf_impl<QLatin1String, QStringView>(); }
667 void indexOf_QLatin1String_QChar_data() { indexOf_data(rhsHasVariableLength: false); }
668 void indexOf_QLatin1String_QChar() { indexOf_impl<QLatin1String, QChar>(); }
669 void indexOf_QLatin1String_char16_t_data() { indexOf_data(rhsHasVariableLength: false); }
670 void indexOf_QLatin1String_char16_t() { indexOf_impl<QLatin1String, char16_t>(); }
671
672 void indexOf_QStringRef_QString_data() { indexOf_data(); }
673 void indexOf_QStringRef_QString() { indexOf_impl<QStringRef, QString>(); }
674 void indexOf_QStringRef_QLatin1String_data() { indexOf_data(); }
675 void indexOf_QStringRef_QLatin1String() { indexOf_impl<QStringRef, QLatin1String>(); }
676 void indexOf_QStringRef_QStringRef_data() { indexOf_data(); }
677 void indexOf_QStringRef_QStringRef() { indexOf_impl<QStringRef, QStringRef>(); }
678 void indexOf_QStringRef_QStringView_data() { indexOf_data(); }
679 void indexOf_QStringRef_QStringView() { indexOf_impl<QStringRef, QStringView>(); }
680 void indexOf_QStringRef_QChar_data() { indexOf_data(rhsHasVariableLength: false); }
681 void indexOf_QStringRef_QChar() { indexOf_impl<QStringRef, QChar>(); }
682 void indexOf_QStringRef_char16_t_data() { indexOf_data(rhsHasVariableLength: false); }
683 void indexOf_QStringRef_char16_t() { indexOf_impl<QStringRef, char16_t>(); }
684
685 void indexOf_QStringView_QString_data() { indexOf_data(); }
686 void indexOf_QStringView_QString() { indexOf_impl<QStringView, QString>(); }
687 void indexOf_QStringView_QLatin1String_data() { indexOf_data(); }
688 void indexOf_QStringView_QLatin1String() { indexOf_impl<QStringView, QLatin1String>(); }
689 void indexOf_QStringView_QStringRef_data() { indexOf_data(); }
690 void indexOf_QStringView_QStringRef() { indexOf_impl<QStringView, QStringRef>(); }
691 void indexOf_QStringView_QStringView_data() { indexOf_data(); }
692 void indexOf_QStringView_QStringView() { indexOf_impl<QStringView, QStringView>(); }
693 void indexOf_QStringView_QChar_data() { indexOf_data(rhsHasVariableLength: false); }
694 void indexOf_QStringView_QChar() { indexOf_impl<QStringView, QChar>(); }
695 void indexOf_QStringView_char16_t_data() { indexOf_data(rhsHasVariableLength: false); }
696 void indexOf_QStringView_char16_t() { indexOf_impl<QStringView, char16_t>(); }
697
698private:
699 template <typename Haystack, typename Needle> void contains_impl() const;
700 void contains_data(bool rhsHasVariableLength = true);
701
702private Q_SLOTS:
703 // test all combinations of {QString, QLatin1String, QStringRef, QStringView} x {QString, QLatin1String, QStringRef, QStringView, QChar, char16_t}:
704 void contains_QString_QString_data() { contains_data(); }
705 void contains_QString_QString() { contains_impl<QString, QString>(); }
706 void contains_QString_QLatin1String_data() { contains_data(); }
707 void contains_QString_QLatin1String() { contains_impl<QString, QLatin1String>(); }
708 void contains_QString_QStringRef_data() { contains_data(); }
709 void contains_QString_QStringRef() { contains_impl<QString, QStringRef>(); }
710 void contains_QString_QStringView_data() { contains_data(); }
711 void contains_QString_QStringView() { contains_impl<QString, QStringView>(); }
712 void contains_QString_QChar_data() { contains_data(rhsHasVariableLength: false); }
713 void contains_QString_QChar() { contains_impl<QString, QChar>(); }
714 void contains_QString_char16_t_data() { contains_data(rhsHasVariableLength: false); }
715 void contains_QString_char16_t() { contains_impl<QString, char16_t>(); }
716
717 void contains_QLatin1String_QString_data() { contains_data(); }
718 void contains_QLatin1String_QString() { contains_impl<QLatin1String, QString>(); }
719 void contains_QLatin1String_QLatin1String_data() { contains_data(); }
720 void contains_QLatin1String_QLatin1String() { contains_impl<QLatin1String, QLatin1String>(); }
721 void contains_QLatin1String_QStringRef_data() { contains_data(); }
722 void contains_QLatin1String_QStringRef() { contains_impl<QLatin1String, QStringRef>(); }
723 void contains_QLatin1String_QStringView_data() { contains_data(); }
724 void contains_QLatin1String_QStringView() { contains_impl<QLatin1String, QStringView>(); }
725 void contains_QLatin1String_QChar_data() { contains_data(rhsHasVariableLength: false); }
726 void contains_QLatin1String_QChar() { contains_impl<QLatin1String, QChar>(); }
727 void contains_QLatin1String_char16_t_data() { contains_data(rhsHasVariableLength: false); }
728 void contains_QLatin1String_char16_t() { contains_impl<QLatin1String, char16_t>(); }
729
730 void contains_QStringRef_QString_data() { contains_data(); }
731 void contains_QStringRef_QString() { contains_impl<QStringRef, QString>(); }
732 void contains_QStringRef_QLatin1String_data() { contains_data(); }
733 void contains_QStringRef_QLatin1String() { contains_impl<QStringRef, QLatin1String>(); }
734 void contains_QStringRef_QStringRef_data() { contains_data(); }
735 void contains_QStringRef_QStringRef() { contains_impl<QStringRef, QStringRef>(); }
736 void contains_QStringRef_QStringView_data() { contains_data(); }
737 void contains_QStringRef_QStringView() { contains_impl<QStringRef, QStringView>(); }
738 void contains_QStringRef_QChar_data() { contains_data(rhsHasVariableLength: false); }
739 void contains_QStringRef_QChar() { contains_impl<QStringRef, QChar>(); }
740 void contains_QStringRef_char16_t_data() { contains_data(rhsHasVariableLength: false); }
741 void contains_QStringRef_char16_t() { contains_impl<QStringRef, char16_t>(); }
742
743 void contains_QStringView_QString_data() { contains_data(); }
744 void contains_QStringView_QString() { contains_impl<QStringView, QString>(); }
745 void contains_QStringView_QLatin1String_data() { contains_data(); }
746 void contains_QStringView_QLatin1String() { contains_impl<QStringView, QLatin1String>(); }
747 void contains_QStringView_QStringRef_data() { contains_data(); }
748 void contains_QStringView_QStringRef() { contains_impl<QStringView, QStringRef>(); }
749 void contains_QStringView_QStringView_data() { contains_data(); }
750 void contains_QStringView_QStringView() { contains_impl<QStringView, QStringView>(); }
751 void contains_QStringView_QChar_data() { contains_data(rhsHasVariableLength: false); }
752 void contains_QStringView_QChar() { contains_impl<QStringView, QChar>(); }
753 void contains_QStringView_char16_t_data() { contains_data(rhsHasVariableLength: false); }
754 void contains_QStringView_char16_t() { contains_impl<QStringView, char16_t>(); }
755
756private:
757 template <typename Haystack, typename Needle> void lastIndexOf_impl() const;
758 void lastIndexOf_data(bool rhsHasVariableLength = true);
759
760private Q_SLOTS:
761 // test all combinations of {QString, QLatin1String, QStringRef, QStringView} x {QString, QLatin1String, QStringRef, QStringView, QChar, char16_t}:
762 void lastIndexOf_QString_QString_data() { lastIndexOf_data(); }
763 void lastIndexOf_QString_QString() { lastIndexOf_impl<QString, QString>(); }
764 void lastIndexOf_QString_QLatin1String_data() { lastIndexOf_data(); }
765 void lastIndexOf_QString_QLatin1String() { lastIndexOf_impl<QString, QLatin1String>(); }
766 void lastIndexOf_QString_QStringRef_data() { lastIndexOf_data(); }
767 void lastIndexOf_QString_QStringRef() { lastIndexOf_impl<QString, QStringRef>(); }
768 void lastIndexOf_QString_QStringView_data() { lastIndexOf_data(); }
769 void lastIndexOf_QString_QStringView() { lastIndexOf_impl<QString, QStringView>(); }
770 void lastIndexOf_QString_QChar_data() { lastIndexOf_data(rhsHasVariableLength: false); }
771 void lastIndexOf_QString_QChar() { lastIndexOf_impl<QString, QChar>(); }
772 void lastIndexOf_QString_char16_t_data() { lastIndexOf_data(rhsHasVariableLength: false); }
773 void lastIndexOf_QString_char16_t() { lastIndexOf_impl<QString, char16_t>(); }
774
775 void lastIndexOf_QLatin1String_QString_data() { lastIndexOf_data(); }
776 void lastIndexOf_QLatin1String_QString() { lastIndexOf_impl<QLatin1String, QString>(); }
777 void lastIndexOf_QLatin1String_QLatin1String_data() { lastIndexOf_data(); }
778 void lastIndexOf_QLatin1String_QLatin1String() { lastIndexOf_impl<QLatin1String, QLatin1String>(); }
779 void lastIndexOf_QLatin1String_QStringRef_data() { lastIndexOf_data(); }
780 void lastIndexOf_QLatin1String_QStringRef() { lastIndexOf_impl<QLatin1String, QStringRef>(); }
781 void lastIndexOf_QLatin1String_QStringView_data() { lastIndexOf_data(); }
782 void lastIndexOf_QLatin1String_QStringView() { lastIndexOf_impl<QLatin1String, QStringView>(); }
783 void lastIndexOf_QLatin1String_QChar_data() { lastIndexOf_data(rhsHasVariableLength: false); }
784 void lastIndexOf_QLatin1String_QChar() { lastIndexOf_impl<QLatin1String, QChar>(); }
785 void lastIndexOf_QLatin1String_char16_t_data() { lastIndexOf_data(rhsHasVariableLength: false); }
786 void lastIndexOf_QLatin1String_char16_t() { lastIndexOf_impl<QLatin1String, char16_t>(); }
787
788 void lastIndexOf_QStringRef_QString_data() { lastIndexOf_data(); }
789 void lastIndexOf_QStringRef_QString() { lastIndexOf_impl<QStringRef, QString>(); }
790 void lastIndexOf_QStringRef_QLatin1String_data() { lastIndexOf_data(); }
791 void lastIndexOf_QStringRef_QLatin1String() { lastIndexOf_impl<QStringRef, QLatin1String>(); }
792 void lastIndexOf_QStringRef_QStringRef_data() { lastIndexOf_data(); }
793 void lastIndexOf_QStringRef_QStringRef() { lastIndexOf_impl<QStringRef, QStringRef>(); }
794 void lastIndexOf_QStringRef_QStringView_data() { lastIndexOf_data(); }
795 void lastIndexOf_QStringRef_QStringView() { lastIndexOf_impl<QStringRef, QStringView>(); }
796 void lastIndexOf_QStringRef_QChar_data() { lastIndexOf_data(rhsHasVariableLength: false); }
797 void lastIndexOf_QStringRef_QChar() { lastIndexOf_impl<QStringRef, QChar>(); }
798 void lastIndexOf_QStringRef_char16_t_data() { lastIndexOf_data(rhsHasVariableLength: false); }
799 void lastIndexOf_QStringRef_char16_t() { lastIndexOf_impl<QStringRef, char16_t>(); }
800
801 void lastIndexOf_QStringView_QString_data() { lastIndexOf_data(); }
802 void lastIndexOf_QStringView_QString() { lastIndexOf_impl<QStringView, QString>(); }
803 void lastIndexOf_QStringView_QLatin1String_data() { lastIndexOf_data(); }
804 void lastIndexOf_QStringView_QLatin1String() { lastIndexOf_impl<QStringView, QLatin1String>(); }
805 void lastIndexOf_QStringView_QStringRef_data() { lastIndexOf_data(); }
806 void lastIndexOf_QStringView_QStringRef() { lastIndexOf_impl<QStringView, QStringRef>(); }
807 void lastIndexOf_QStringView_QStringView_data() { lastIndexOf_data(); }
808 void lastIndexOf_QStringView_QStringView() { lastIndexOf_impl<QStringView, QStringView>(); }
809 void lastIndexOf_QStringView_QChar_data() { lastIndexOf_data(rhsHasVariableLength: false); }
810 void lastIndexOf_QStringView_QChar() { lastIndexOf_impl<QStringView, QChar>(); }
811 void lastIndexOf_QStringView_char16_t_data() { lastIndexOf_data(rhsHasVariableLength: false); }
812 void lastIndexOf_QStringView_char16_t() { lastIndexOf_impl<QStringView, char16_t>(); }
813};
814
815void tst_QStringApiSymmetry::compare_data(bool hasConceptOfNullAndEmpty)
816{
817 QTest::addColumn<QStringRef>(name: "lhsUnicode");
818 QTest::addColumn<QLatin1String>(name: "lhsLatin1");
819 QTest::addColumn<QStringRef>(name: "rhsUnicode");
820 QTest::addColumn<QLatin1String>(name: "rhsLatin1");
821 QTest::addColumn<int>(name: "caseSensitiveCompareResult");
822 QTest::addColumn<int>(name: "caseInsensitiveCompareResult");
823
824 if (hasConceptOfNullAndEmpty) {
825 QTest::newRow(dataTag: "null <> null") << QStringRef() << QLatin1String()
826 << QStringRef() << QLatin1String()
827 << 0 << 0;
828 static const QString empty("");
829 QTest::newRow(dataTag: "null <> empty") << QStringRef() << QLatin1String()
830 << QStringRef(&empty) << QLatin1String("")
831 << 0 << 0;
832 QTest::newRow(dataTag: "empty <> null") << QStringRef(&empty) << QLatin1String("")
833 << QStringRef() << QLatin1String()
834 << 0 << 0;
835 }
836
837#define ROW(lhs, rhs) \
838 do { \
839 static const QString pinned[] = { \
840 QString(QLatin1String(lhs)), \
841 QString(QLatin1String(rhs)), \
842 }; \
843 QTest::newRow(qUtf8Printable(QLatin1String("'" lhs "' <> '" rhs "': "))) \
844 << QStringRef(&pinned[0]) << QLatin1String(lhs) \
845 << QStringRef(&pinned[1]) << QLatin1String(rhs) \
846 << sign(qstrcmp(lhs, rhs)) << sign(qstricmp(lhs, rhs)); \
847 } while (false)
848 ROW("", "0");
849 ROW("0", "");
850 ROW("0", "1");
851 ROW("0", "0");
852 ROW("10", "0");
853 ROW("01", "1");
854 ROW("\xE4", "\xE4"); // ä <> ä
855 ROW("\xE4", "\xC4"); // ä <> Ä
856#undef ROW
857}
858
859template <typename String> String detached(String s)
860{
861 if (!s.isNull()) { // detaching loses nullness, but we need to preserve it
862 auto d = s.data();
863 Q_UNUSED(d);
864 }
865 return s;
866}
867
868template <class Str> Str make(const QStringRef &sf, QLatin1String l1, const QByteArray &u8);
869template <> QChar make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf.isEmpty() ? QChar() : sf.at(i: 0); }
870template <> char16_t make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf.isEmpty() ? char16_t() : char16_t{sf.at(i: 0).unicode()}; }
871template <> QStringRef make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf; }
872template <> QString make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf.toString(); }
873template <> QStringView make(const QStringRef &sf, QLatin1String, const QByteArray &) { return sf; }
874template <> QLatin1String make(const QStringRef &, QLatin1String l1, const QByteArray &) { return l1; }
875template <> QByteArray make(const QStringRef &, QLatin1String, const QByteArray &u8) { return u8; }
876template <> const char * make(const QStringRef &, QLatin1String, const QByteArray &u8) { return u8.data(); }
877
878template <typename> struct is_utf8_encoded : std::false_type {};
879template <> struct is_utf8_encoded<const char*> : std::true_type {};
880template <> struct is_utf8_encoded<QByteArray> : std::true_type {};
881
882template <typename> struct is_latin1_encoded : std::false_type {};
883template <> struct is_latin1_encoded<QLatin1String> : std::true_type {};
884
885template <typename LHS, typename RHS>
886struct has_nothrow_compare {
887 enum { value = is_utf8_encoded<LHS>::value == is_utf8_encoded<RHS>::value };
888};
889
890template <typename LHS, typename RHS>
891struct has_qCompareStrings {
892 enum { value = !std::is_same<LHS, QChar>::value && !std::is_same<RHS, QChar>::value &&
893 !is_utf8_encoded<LHS>::value && !is_utf8_encoded<RHS>::value };
894};
895
896template <typename LHS, typename RHS>
897void tst_QStringApiSymmetry::compare_impl() const
898{
899 QFETCH(QStringRef, lhsUnicode);
900 QFETCH(QLatin1String, lhsLatin1);
901 QFETCH(QStringRef, rhsUnicode);
902 QFETCH(QLatin1String, rhsLatin1);
903 QFETCH(int, caseSensitiveCompareResult);
904 QFETCH(const int, caseInsensitiveCompareResult);
905 Q_UNUSED(caseInsensitiveCompareResult);
906
907 const auto lhsU8 = lhsUnicode.toUtf8();
908 const auto rhsU8 = rhsUnicode.toUtf8();
909
910 const auto lhs = make<LHS>(lhsUnicode, lhsLatin1, lhsU8);
911 const auto rhs = make<RHS>(rhsUnicode, rhsLatin1, rhsU8);
912
913#define CHECK(op) \
914 QVERIFY_NOEXCEPT(lhs op rhs); \
915 do { if (caseSensitiveCompareResult op 0) { \
916 QVERIFY(lhs op rhs); \
917 } else { \
918 QVERIFY(!(lhs op rhs)); \
919 } } while (false)
920
921 CHECK(==);
922 CHECK(!=);
923 CHECK(<);
924 CHECK(>);
925 CHECK(<=);
926 CHECK(>=);
927#undef CHECK
928}
929
930template <typename LHS, typename RHS>
931void tst_QStringApiSymmetry::member_compare_impl() const
932{
933 QFETCH(QStringRef, lhsUnicode);
934 QFETCH(QLatin1String, lhsLatin1);
935 QFETCH(QStringRef, rhsUnicode);
936 QFETCH(QLatin1String, rhsLatin1);
937 QFETCH(const int, caseSensitiveCompareResult);
938 QFETCH(const int, caseInsensitiveCompareResult);
939
940 const auto lhsU8 = lhsUnicode.toUtf8();
941 const auto rhsU8 = rhsUnicode.toUtf8();
942
943 const auto lhs = make<LHS>(lhsUnicode, lhsLatin1, lhsU8);
944 const auto rhs = make<RHS>(rhsUnicode, rhsLatin1, rhsU8);
945
946 QVERIFY_NOEXCEPT(lhs.compare(rhs, Qt::CaseSensitive));
947
948 QCOMPARE(sign(lhs.compare(rhs)), caseSensitiveCompareResult);
949 QCOMPARE(sign(lhs.compare(rhs, Qt::CaseSensitive)), caseSensitiveCompareResult);
950 if (is_utf8_encoded<LHS>::value && is_utf8_encoded<RHS>::value &&
951 caseSensitiveCompareResult != caseInsensitiveCompareResult &&
952 (!QtPrivate::isAscii(s: lhsUnicode) || !QtPrivate::isAscii(s: rhsUnicode)))
953 {
954 QEXPECT_FAIL("", "Qt is missing a case-insensitive UTF-8/UTF-8 comparator", Continue);
955 }
956 QCOMPARE(sign(lhs.compare(rhs, Qt::CaseInsensitive)), caseInsensitiveCompareResult);
957}
958
959static QString empty = QLatin1String("");
960static QString null;
961// the tests below rely on the fact that these objects' names match their contents:
962static QString a = QStringLiteral("a");
963static QString A = QStringLiteral("A");
964static QString b = QStringLiteral("b");
965static QString B = QStringLiteral("B");
966static QString c = QStringLiteral("c");
967static QString C = QStringLiteral("C");
968static QString d = QStringLiteral("d");
969static QString D = QStringLiteral("D");
970static QString e = QStringLiteral("e");
971static QString E = QStringLiteral("E");
972static QString f = QStringLiteral("f");
973static QString F = QStringLiteral("F");
974static QString g = QStringLiteral("g");
975static QString G = QStringLiteral("G");
976static QString ab = QStringLiteral("ab");
977static QString aB = QStringLiteral("aB");
978static QString Ab = QStringLiteral("Ab");
979static QString AB = QStringLiteral("AB");
980static QString bc = QStringLiteral("bc");
981static QString bC = QStringLiteral("bC");
982static QString Bc = QStringLiteral("Bc");
983static QString BC = QStringLiteral("BC");
984static QString abc = QStringLiteral("abc");
985static QString abC = QStringLiteral("abC");
986static QString aBc = QStringLiteral("aBc");
987static QString aBC = QStringLiteral("aBC");
988static QString Abc = QStringLiteral("Abc");
989static QString AbC = QStringLiteral("AbC");
990static QString ABc = QStringLiteral("ABc");
991static QString ABC = QStringLiteral("ABC");
992
993void tst_QStringApiSymmetry::startsWith_data(bool rhsHasVariableLength)
994{
995 QTest::addColumn<QStringRef>(name: "haystackU16");
996 QTest::addColumn<QLatin1String>(name: "haystackL1");
997 QTest::addColumn<QStringRef>(name: "needleU16");
998 QTest::addColumn<QLatin1String>(name: "needleL1");
999 QTest::addColumn<bool>(name: "resultCS");
1000 QTest::addColumn<bool>(name: "resultCIS");
1001
1002 if (rhsHasVariableLength) {
1003 QTest::addRow(format: "null ~= ^null") << QStringRef() << QLatin1String()
1004 << QStringRef() << QLatin1String() << true << true;
1005 QTest::addRow(format: "empty ~= ^null") << QStringRef(&empty) << QLatin1String("")
1006 << QStringRef() << QLatin1String() << true << true;
1007 QTest::addRow(format: "a ~= ^null") << QStringRef(&a) << QLatin1String("a")
1008 << QStringRef() << QLatin1String() << true << true;
1009 QTest::addRow(format: "null ~= ^empty") << QStringRef() << QLatin1String()
1010 << QStringRef(&empty) << QLatin1String("") << false << false;
1011 QTest::addRow(format: "a ~= ^empty") << QStringRef(&a) << QLatin1String("a")
1012 << QStringRef(&empty) << QLatin1String("") << true << true;
1013 QTest::addRow(format: "empty ~= ^empty") << QStringRef(&empty) << QLatin1String("")
1014 << QStringRef(&empty) << QLatin1String("") << true << true;
1015 }
1016 QTest::addRow(format: "null ~= ^a") << QStringRef() << QLatin1String()
1017 << QStringRef(&a) << QLatin1String("a") << false << false;
1018 QTest::addRow(format: "empty ~= ^a") << QStringRef(&empty) << QLatin1String("")
1019 << QStringRef(&a) << QLatin1String("a") << false << false;
1020
1021#define ROW(h, n, cs, cis) \
1022 QTest::addRow("%s ~= ^%s", #h, #n) << QStringRef(&h) << QLatin1String(#h) \
1023 << QStringRef(&n) << QLatin1String(#n) \
1024 << bool(cs) << bool(cis)
1025 ROW(a, a, 1, 1);
1026 ROW(a, A, 0, 1);
1027 ROW(a, b, 0, 0);
1028
1029 if (rhsHasVariableLength)
1030 ROW(a, aB, 0, 0);
1031
1032 ROW(ab, a, 1, 1);
1033 if (rhsHasVariableLength) {
1034 ROW(ab, ab, 1, 1);
1035 ROW(ab, aB, 0, 1);
1036 ROW(ab, Ab, 0, 1);
1037 }
1038 ROW(ab, c, 0, 0);
1039
1040 if (rhsHasVariableLength)
1041 ROW(ab, abc, 0, 0);
1042
1043 ROW(Abc, c, 0, 0);
1044 if (rhsHasVariableLength) {
1045 ROW(Abc, ab, 0, 1);
1046 ROW(Abc, aB, 0, 1);
1047 ROW(Abc, Ab, 1, 1);
1048 ROW(Abc, AB, 0, 1);
1049 ROW(aBC, ab, 0, 1);
1050 ROW(aBC, aB, 1, 1);
1051 ROW(aBC, Ab, 0, 1);
1052 ROW(aBC, AB, 0, 1);
1053 }
1054 ROW(ABC, b, 0, 0);
1055 ROW(ABC, a, 0, 1);
1056#undef ROW
1057}
1058
1059template <typename Haystack, typename Needle>
1060void tst_QStringApiSymmetry::startsWith_impl() const
1061{
1062 QFETCH(const QStringRef, haystackU16);
1063 QFETCH(const QLatin1String, haystackL1);
1064 QFETCH(const QStringRef, needleU16);
1065 QFETCH(const QLatin1String, needleL1);
1066 QFETCH(const bool, resultCS);
1067 QFETCH(const bool, resultCIS);
1068
1069 const auto haystackU8 = haystackU16.toUtf8();
1070 const auto needleU8 = needleU16.toUtf8();
1071
1072 const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
1073 const auto needle = make<Needle>(needleU16, needleL1, needleU8);
1074
1075 QCOMPARE(haystack.startsWith(needle), resultCS);
1076 QCOMPARE(haystack.startsWith(needle, Qt::CaseSensitive), resultCS);
1077 QCOMPARE(haystack.startsWith(needle, Qt::CaseInsensitive), resultCIS);
1078}
1079
1080void tst_QStringApiSymmetry::endsWith_data(bool rhsHasVariableLength)
1081{
1082 QTest::addColumn<QStringRef>(name: "haystackU16");
1083 QTest::addColumn<QLatin1String>(name: "haystackL1");
1084 QTest::addColumn<QStringRef>(name: "needleU16");
1085 QTest::addColumn<QLatin1String>(name: "needleL1");
1086 QTest::addColumn<bool>(name: "resultCS");
1087 QTest::addColumn<bool>(name: "resultCIS");
1088
1089 if (rhsHasVariableLength) {
1090 QTest::addRow(format: "null ~= null$") << QStringRef() << QLatin1String()
1091 << QStringRef() << QLatin1String() << true << true;
1092 QTest::addRow(format: "empty ~= null$") << QStringRef(&empty) << QLatin1String("")
1093 << QStringRef() << QLatin1String() << true << true;
1094 QTest::addRow(format: "a ~= null$") << QStringRef(&a) << QLatin1String("a")
1095 << QStringRef() << QLatin1String() << true << true;
1096 QTest::addRow(format: "null ~= empty$") << QStringRef() << QLatin1String()
1097 << QStringRef(&empty) << QLatin1String("") << false << false;
1098 QTest::addRow(format: "a ~= empty$") << QStringRef(&a) << QLatin1String("a")
1099 << QStringRef(&empty) << QLatin1String("") << true << true;
1100 QTest::addRow(format: "empty ~= empty$") << QStringRef(&empty) << QLatin1String("")
1101 << QStringRef(&empty) << QLatin1String("") << true << true;
1102 }
1103 QTest::addRow(format: "null ~= a$") << QStringRef() << QLatin1String()
1104 << QStringRef(&a) << QLatin1String("a") << false << false;
1105 QTest::addRow(format: "empty ~= a$") << QStringRef(&empty) << QLatin1String("")
1106 << QStringRef(&a) << QLatin1String("a") << false << false;
1107
1108#define ROW(h, n, cs, cis) \
1109 QTest::addRow("%s ~= %s$", #h, #n) << QStringRef(&h) << QLatin1String(#h) \
1110 << QStringRef(&n) << QLatin1String(#n) \
1111 << bool(cs) << bool(cis)
1112 ROW(a, a, 1, 1);
1113 ROW(a, A, 0, 1);
1114 ROW(a, b, 0, 0);
1115
1116 if (rhsHasVariableLength)
1117 ROW(b, ab, 0, 0);
1118
1119 ROW(ab, b, 1, 1);
1120 if (rhsHasVariableLength) {
1121 ROW(ab, ab, 1, 1);
1122 ROW(ab, aB, 0, 1);
1123 ROW(ab, Ab, 0, 1);
1124 }
1125 ROW(ab, c, 0, 0);
1126
1127 if (rhsHasVariableLength)
1128 ROW(bc, abc, 0, 0);
1129
1130 ROW(Abc, c, 1, 1);
1131 if (rhsHasVariableLength) {
1132 ROW(Abc, bc, 1, 1);
1133 ROW(Abc, bC, 0, 1);
1134 ROW(Abc, Bc, 0, 1);
1135 ROW(Abc, BC, 0, 1);
1136 ROW(aBC, bc, 0, 1);
1137 ROW(aBC, bC, 0, 1);
1138 ROW(aBC, Bc, 0, 1);
1139 ROW(aBC, BC, 1, 1);
1140 }
1141 ROW(ABC, b, 0, 0);
1142 ROW(ABC, a, 0, 0);
1143#undef ROW
1144}
1145
1146template <typename Haystack, typename Needle>
1147void tst_QStringApiSymmetry::endsWith_impl() const
1148{
1149 QFETCH(const QStringRef, haystackU16);
1150 QFETCH(const QLatin1String, haystackL1);
1151 QFETCH(const QStringRef, needleU16);
1152 QFETCH(const QLatin1String, needleL1);
1153 QFETCH(const bool, resultCS);
1154 QFETCH(const bool, resultCIS);
1155
1156 const auto haystackU8 = haystackU16.toUtf8();
1157 const auto needleU8 = needleU16.toUtf8();
1158
1159 const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
1160 const auto needle = make<Needle>(needleU16, needleL1, needleU8);
1161
1162 QCOMPARE(haystack.endsWith(needle), resultCS);
1163 QCOMPARE(haystack.endsWith(needle, Qt::CaseSensitive), resultCS);
1164 QCOMPARE(haystack.endsWith(needle, Qt::CaseInsensitive), resultCIS);
1165}
1166
1167void tst_QStringApiSymmetry::split_data(bool rhsHasVariableLength)
1168{
1169 QTest::addColumn<QStringRef>(name: "haystackU16");
1170 QTest::addColumn<QLatin1String>(name: "haystackL1");
1171 QTest::addColumn<QStringRef>(name: "needleU16");
1172 QTest::addColumn<QLatin1String>(name: "needleL1");
1173 QTest::addColumn<QStringList>(name: "resultCS");
1174 QTest::addColumn<QStringList>(name: "resultCIS");
1175
1176 if (rhsHasVariableLength) {
1177 QTest::addRow(format: "null ~= null$") << QStringRef{} << QLatin1String{}
1178 << QStringRef{} << QLatin1String{}
1179 << QStringList{{}, {}} << QStringList{{}, {}};
1180 QTest::addRow(format: "empty ~= null$") << QStringRef{&empty} << QLatin1String("")
1181 << QStringRef{} << QLatin1String{}
1182 << QStringList{empty, empty} << QStringList{empty, empty};
1183 QTest::addRow(format: "a ~= null$") << QStringRef{&a} << QLatin1String{"a"}
1184 << QStringRef{} << QLatin1String{}
1185 << QStringList{empty, a, empty} << QStringList{empty, a, empty};
1186 QTest::addRow(format: "null ~= empty$") << QStringRef{} << QLatin1String{}
1187 << QStringRef{&empty} << QLatin1String{""}
1188 << QStringList{{}, {}} << QStringList{{}, {}};
1189 QTest::addRow(format: "a ~= empty$") << QStringRef{&a} << QLatin1String{"a"}
1190 << QStringRef{&empty} << QLatin1String{""}
1191 << QStringList{empty, a, empty} << QStringList{empty, a, empty};
1192 QTest::addRow(format: "empty ~= empty$") << QStringRef{&empty} << QLatin1String{""}
1193 << QStringRef{&empty} << QLatin1String{""}
1194 << QStringList{empty, empty} << QStringList{empty, empty};
1195 }
1196 QTest::addRow(format: "null ~= a$") << QStringRef{} << QLatin1String{}
1197 << QStringRef{&a} << QLatin1String{"a"}
1198 << QStringList{{}} << QStringList{{}};
1199 QTest::addRow(format: "empty ~= a$") << QStringRef{&empty} << QLatin1String{""}
1200 << QStringRef{&a} << QLatin1String{"a"}
1201 << QStringList{empty} << QStringList{empty};
1202
1203#define ROW(h, n, cs, cis) \
1204 QTest::addRow("%s ~= %s$", #h, #n) << QStringRef(&h) << QLatin1String(#h) \
1205 << QStringRef(&n) << QLatin1String(#n) \
1206 << QStringList cs << QStringList cis
1207 ROW(a, a, ({empty, empty}), ({empty, empty}));
1208 ROW(a, A, {a}, ({empty, empty}));
1209 ROW(a, b, {a}, {a});
1210
1211 if (rhsHasVariableLength)
1212 ROW(b, ab, {b}, {b});
1213
1214 ROW(ab, b, ({a, empty}), ({a, empty}));
1215 if (rhsHasVariableLength) {
1216 ROW(ab, ab, ({empty, empty}), ({empty, empty}));
1217 ROW(ab, aB, {ab}, ({empty, empty}));
1218 ROW(ab, Ab, {ab}, ({empty, empty}));
1219 }
1220 ROW(ab, c, {ab}, {ab});
1221
1222 if (rhsHasVariableLength)
1223 ROW(bc, abc, {bc}, {bc});
1224
1225 ROW(Abc, c, ({Ab, empty}), ({Ab, empty}));
1226#if 0
1227 if (rhsHasVariableLength) {
1228 ROW(Abc, bc, 1, 1);
1229 ROW(Abc, bC, 0, 1);
1230 ROW(Abc, Bc, 0, 1);
1231 ROW(Abc, BC, 0, 1);
1232 ROW(aBC, bc, 0, 1);
1233 ROW(aBC, bC, 0, 1);
1234 ROW(aBC, Bc, 0, 1);
1235 ROW(aBC, BC, 1, 1);
1236 }
1237#endif
1238 ROW(ABC, b, {ABC}, ({A, C}));
1239 ROW(ABC, a, {ABC}, ({empty, BC}));
1240#undef ROW
1241}
1242
1243static QStringList skipped(const QStringList &sl)
1244{
1245 QStringList result;
1246 result.reserve(alloc: sl.size());
1247 for (const QString &s : sl) {
1248 if (!s.isEmpty())
1249 result.push_back(t: s);
1250 }
1251 return result;
1252}
1253
1254template <typename Haystack, typename Needle>
1255void tst_QStringApiSymmetry::split_impl() const
1256{
1257 QFETCH(const QStringRef, haystackU16);
1258 QFETCH(const QLatin1String, haystackL1);
1259 QFETCH(const QStringRef, needleU16);
1260 QFETCH(const QLatin1String, needleL1);
1261 QFETCH(const QStringList, resultCS);
1262 QFETCH(const QStringList, resultCIS);
1263
1264 const QStringList skippedResultCS = skipped(sl: resultCS);
1265 const QStringList skippedResultCIS = skipped(sl: resultCIS);
1266
1267 const auto haystackU8 = haystackU16.toUtf8();
1268 const auto needleU8 = needleU16.toUtf8();
1269
1270 const auto haystack = make<Haystack>(haystackU16, haystackL1, haystackU8);
1271 const auto needle = make<Needle>(needleU16, needleL1, needleU8);
1272
1273 QCOMPARE(toQStringList(haystack.split(needle)), resultCS);
1274 QCOMPARE(toQStringList(haystack.split(needle, Qt::KeepEmptyParts, Qt::CaseSensitive)), resultCS);
1275 QCOMPARE(toQStringList(haystack.split(needle, Qt::KeepEmptyParts, Qt::CaseInsensitive)), resultCIS);
1276 QCOMPARE(toQStringList(haystack.split(needle, Qt::SkipEmptyParts, Qt::CaseSensitive)), skippedResultCS);
1277 QCOMPARE(toQStringList(haystack.split(needle, Qt::SkipEmptyParts, Qt::CaseInsensitive)), skippedResultCIS);
1278}
1279
1280void tst_QStringApiSymmetry::mid_data()
1281{
1282 QTest::addColumn<QStringRef>(name: "unicode");
1283 QTest::addColumn<QLatin1String>(name: "latin1");
1284 QTest::addColumn<int>(name: "pos");
1285 QTest::addColumn<int>(name: "n");
1286 QTest::addColumn<QStringRef>(name: "result");
1287 QTest::addColumn<QStringRef>(name: "result2");
1288
1289 QTest::addRow(format: "null") << QStringRef() << QLatin1String() << 0 << 0 << QStringRef() << QStringRef();
1290 QTest::addRow(format: "empty") << QStringRef(&empty) << QLatin1String("") << 0 << 0 << QStringRef(&empty) << QStringRef(&empty);
1291
1292 // Some classes' mid() implementations have a wide contract, others a narrow one
1293 // so only test valid arguents here:
1294#define ROW(base, p, n, r1, r2) \
1295 QTest::addRow("%s%d%d", #base, p, n) << QStringRef(&base) << QLatin1String(#base) << p << n << QStringRef(&r1) << QStringRef(&r2)
1296
1297 ROW(a, 0, 0, a, empty);
1298 ROW(a, 0, 1, a, a);
1299 ROW(a, 1, 0, empty, empty);
1300
1301 ROW(ab, 0, 0, ab, empty);
1302 ROW(ab, 0, 1, ab, a);
1303 ROW(ab, 0, 2, ab, ab);
1304 ROW(ab, 1, 0, b, empty);
1305 ROW(ab, 1, 1, b, b);
1306 ROW(ab, 2, 0, empty, empty);
1307
1308 ROW(abc, 0, 0, abc, empty);
1309 ROW(abc, 0, 1, abc, a);
1310 ROW(abc, 0, 2, abc, ab);
1311 ROW(abc, 0, 3, abc, abc);
1312 ROW(abc, 1, 0, bc, empty);
1313 ROW(abc, 1, 1, bc, b);
1314 ROW(abc, 1, 2, bc, bc);
1315 ROW(abc, 2, 0, c, empty);
1316 ROW(abc, 2, 1, c, c);
1317 ROW(abc, 3, 0, empty, empty);
1318#undef ROW
1319}
1320
1321template <typename String>
1322void tst_QStringApiSymmetry::mid_impl()
1323{
1324 QFETCH(const QStringRef, unicode);
1325 QFETCH(const QLatin1String, latin1);
1326 QFETCH(const int, pos);
1327 QFETCH(const int, n);
1328 QFETCH(const QStringRef, result);
1329 QFETCH(const QStringRef, result2);
1330
1331 const auto utf8 = unicode.toUtf8();
1332
1333 const auto s = make<String>(unicode, latin1, utf8);
1334
1335 {
1336 const auto mid = s.mid(pos);
1337 const auto mid2 = s.mid(pos, n);
1338
1339 QCOMPARE(mid, result);
1340 QCOMPARE(mid.isNull(), result.isNull());
1341 QCOMPARE(mid.isEmpty(), result.isEmpty());
1342
1343 QCOMPARE(mid2, result2);
1344 QCOMPARE(mid2.isNull(), result2.isNull());
1345 QCOMPARE(mid2.isEmpty(), result2.isEmpty());
1346 }
1347 {
1348 const auto mid = detached(s).mid(pos);
1349 const auto mid2 = detached(s).mid(pos, n);
1350
1351 QCOMPARE(mid, result);
1352 QCOMPARE(mid.isNull(), result.isNull());
1353 QCOMPARE(mid.isEmpty(), result.isEmpty());
1354
1355 QCOMPARE(mid2, result2);
1356 QCOMPARE(mid2.isNull(), result2.isNull());
1357 QCOMPARE(mid2.isEmpty(), result2.isEmpty());
1358 }
1359}
1360
1361void tst_QStringApiSymmetry::left_data()
1362{
1363 QTest::addColumn<QStringRef>(name: "unicode");
1364 QTest::addColumn<QLatin1String>(name: "latin1");
1365 QTest::addColumn<int>(name: "n");
1366 QTest::addColumn<QStringRef>(name: "result");
1367
1368 QTest::addRow(format: "null") << QStringRef() << QLatin1String() << 0 << QStringRef();
1369 QTest::addRow(format: "empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty);
1370
1371 // Some classes' left() implementations have a wide contract, others a narrow one
1372 // so only test valid arguents here:
1373#define ROW(base, n, res) \
1374 QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res);
1375
1376 ROW(a, 0, empty);
1377 ROW(a, 1, a);
1378
1379 ROW(ab, 0, empty);
1380 ROW(ab, 1, a);
1381 ROW(ab, 2, ab);
1382
1383 ROW(abc, 0, empty);
1384 ROW(abc, 1, a);
1385 ROW(abc, 2, ab);
1386 ROW(abc, 3, abc);
1387#undef ROW
1388}
1389
1390template <typename String>
1391void tst_QStringApiSymmetry::left_impl()
1392{
1393 QFETCH(const QStringRef, unicode);
1394 QFETCH(const QLatin1String, latin1);
1395 QFETCH(const int, n);
1396 QFETCH(const QStringRef, result);
1397
1398 const auto utf8 = unicode.toUtf8();
1399
1400 const auto s = make<String>(unicode, latin1, utf8);
1401
1402 {
1403 const auto left = s.left(n);
1404
1405 QCOMPARE(left, result);
1406 QCOMPARE(left.isNull(), result.isNull());
1407 QCOMPARE(left.isEmpty(), result.isEmpty());
1408 }
1409 {
1410 const auto left = detached(s).left(n);
1411
1412 QCOMPARE(left, result);
1413 QCOMPARE(left.isNull(), result.isNull());
1414 QCOMPARE(left.isEmpty(), result.isEmpty());
1415 }
1416 {
1417 auto left = s;
1418 left.truncate(n);
1419
1420 QCOMPARE(left, result);
1421 QCOMPARE(left.isNull(), result.isNull());
1422 QCOMPARE(left.isEmpty(), result.isEmpty());
1423 }
1424}
1425
1426void tst_QStringApiSymmetry::right_data()
1427{
1428 QTest::addColumn<QStringRef>(name: "unicode");
1429 QTest::addColumn<QLatin1String>(name: "latin1");
1430 QTest::addColumn<int>(name: "n");
1431 QTest::addColumn<QStringRef>(name: "result");
1432
1433 QTest::addRow(format: "null") << QStringRef() << QLatin1String() << 0 << QStringRef();
1434 QTest::addRow(format: "empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty);
1435
1436 // Some classes' right() implementations have a wide contract, others a narrow one
1437 // so only test valid arguents here:
1438#define ROW(base, n, res) \
1439 QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res);
1440
1441 ROW(a, 0, empty);
1442 ROW(a, 1, a);
1443
1444 ROW(ab, 0, empty);
1445 ROW(ab, 1, b);
1446 ROW(ab, 2, ab);
1447
1448 ROW(abc, 0, empty);
1449 ROW(abc, 1, c);
1450 ROW(abc, 2, bc);
1451 ROW(abc, 3, abc);
1452#undef ROW
1453}
1454
1455template <typename String>
1456void tst_QStringApiSymmetry::right_impl()
1457{
1458 QFETCH(const QStringRef, unicode);
1459 QFETCH(const QLatin1String, latin1);
1460 QFETCH(const int, n);
1461 QFETCH(const QStringRef, result);
1462
1463 const auto utf8 = unicode.toUtf8();
1464
1465 const auto s = make<String>(unicode, latin1, utf8);
1466
1467 {
1468 const auto right = s.right(n);
1469
1470 QCOMPARE(right, result);
1471 QCOMPARE(right.isNull(), result.isNull());
1472 QCOMPARE(right.isEmpty(), result.isEmpty());
1473 }
1474 {
1475 const auto right = detached(s).right(n);
1476
1477 QCOMPARE(right, result);
1478 QCOMPARE(right.isNull(), result.isNull());
1479 QCOMPARE(right.isEmpty(), result.isEmpty());
1480 }
1481}
1482
1483void tst_QStringApiSymmetry::chop_data()
1484{
1485 QTest::addColumn<QStringRef>(name: "unicode");
1486 QTest::addColumn<QLatin1String>(name: "latin1");
1487 QTest::addColumn<int>(name: "n");
1488 QTest::addColumn<QStringRef>(name: "result");
1489
1490 QTest::addRow(format: "null") << QStringRef() << QLatin1String() << 0 << QStringRef();
1491 QTest::addRow(format: "empty") << QStringRef(&empty) << QLatin1String("") << 0 << QStringRef(&empty);
1492
1493 // Some classes' truncate() implementations have a wide contract, others a narrow one
1494 // so only test valid arguents here:
1495#define ROW(base, n, res) \
1496 QTest::addRow("%s%d", #base, n) << QStringRef(&base) << QLatin1String(#base) << n << QStringRef(&res);
1497
1498 ROW(a, 0, a);
1499 ROW(a, 1, empty);
1500
1501 ROW(ab, 0, ab);
1502 ROW(ab, 1, a);
1503 ROW(ab, 2, empty);
1504
1505 ROW(abc, 0, abc);
1506 ROW(abc, 1, ab);
1507 ROW(abc, 2, a);
1508 ROW(abc, 3, empty);
1509#undef ROW
1510}
1511
1512template <typename String>
1513void tst_QStringApiSymmetry::chop_impl()
1514{
1515 QFETCH(const QStringRef, unicode);
1516 QFETCH(const QLatin1String, latin1);
1517 QFETCH(const int, n);
1518 QFETCH(const QStringRef, result);
1519
1520 const auto utf8 = unicode.toUtf8();
1521
1522 const auto s = make<String>(unicode, latin1, utf8);
1523
1524 {
1525 const auto chopped = s.chopped(n);
1526
1527 QCOMPARE(chopped, result);
1528 QCOMPARE(chopped.isNull(), result.isNull());
1529 QCOMPARE(chopped.isEmpty(), result.isEmpty());
1530 }
1531 {
1532 const auto chopped = detached(s).chopped(n);
1533
1534 QCOMPARE(chopped, result);
1535 QCOMPARE(chopped.isNull(), result.isNull());
1536 QCOMPARE(chopped.isEmpty(), result.isEmpty());
1537 }
1538 {
1539 auto chopped = s;
1540 chopped.chop(n);
1541
1542 QCOMPARE(chopped, result);
1543 QCOMPARE(chopped.isNull(), result.isNull());
1544 QCOMPARE(chopped.isEmpty(), result.isEmpty());
1545 }
1546}
1547
1548void tst_QStringApiSymmetry::trimmed_data()
1549{
1550 QTest::addColumn<QString>(name: "unicode");
1551 QTest::addColumn<QStringRef>(name: "result");
1552
1553 const auto latin1Whitespace = QLatin1String(" \r\n\t\f\v");
1554
1555 QTest::addRow(format: "null") << QString() << QStringRef();
1556
1557 auto add = [latin1Whitespace](const QString &str) {
1558 // run through all substrings of latin1Whitespace
1559 for (int len = 0; len < latin1Whitespace.size(); ++len) {
1560 for (int pos = 0; pos < latin1Whitespace.size() - len; ++pos) {
1561 const QString unicode = latin1Whitespace.mid(pos, n: len) + str + latin1Whitespace.mid(pos, n: len);
1562 const QScopedArrayPointer<const char> escaped(QTest::toString(str: unicode));
1563 QTest::addRow(format: "%s", escaped.data()) << unicode << QStringRef(&str);
1564 }
1565 }
1566 };
1567
1568 add(empty);
1569 add(a);
1570 add(ab);
1571}
1572
1573template <typename String>
1574void tst_QStringApiSymmetry::trimmed_impl()
1575{
1576 QFETCH(const QString, unicode);
1577 QFETCH(const QStringRef, result);
1578
1579 const auto utf8 = unicode.toUtf8();
1580 const auto l1s = unicode.toLatin1();
1581 const auto l1 = l1s.isNull() ? QLatin1String() : QLatin1String(l1s);
1582
1583 const auto ref = unicode.isNull() ? QStringRef() : QStringRef(&unicode);
1584 const auto s = make<String>(ref, l1, utf8);
1585
1586 QCOMPARE(s.isNull(), unicode.isNull());
1587
1588 {
1589 const auto trimmed = s.trimmed();
1590
1591 QCOMPARE(trimmed, result);
1592 QCOMPARE(trimmed.isNull(), result.isNull());
1593 QCOMPARE(trimmed.isEmpty(), result.isEmpty());
1594 }
1595 {
1596 const auto trimmed = detached(s).trimmed();
1597
1598 QCOMPARE(trimmed, result);
1599 QCOMPARE(trimmed.isNull(), result.isNull());
1600 QCOMPARE(trimmed.isEmpty(), result.isEmpty());
1601 }
1602}
1603
1604//
1605//
1606// UTF-16-only checks:
1607//
1608//
1609
1610template <class Str> Str make(const QString &s);
1611template <> QStringRef make(const QString &s) { return QStringRef(&s); }
1612template <> QString make(const QString &s) { return s; }
1613template <> QStringView make(const QString &s) { return s; }
1614
1615#define REPEAT_16X(X) X X X X X X X X X X X X X X X X
1616#define LONG_STRING_256 REPEAT_16X("0123456789abcdef")
1617
1618void tst_QStringApiSymmetry::toLocal8Bit_data()
1619{
1620 QTest::addColumn<QString>(name: "unicode");
1621 QTest::addColumn<QByteArray>(name: "local");
1622
1623 auto add = [](const char *local) {
1624 const QByteArray ba(local);
1625 QString s;
1626 for (char c : ba)
1627 s += QLatin1Char(c);
1628 QTest::newRow(dataTag: rowName(data: ba).constData()) << s << ba;
1629 };
1630
1631 QTest::addRow(format: "null") << QString() << QByteArray();
1632 QTest::addRow(format: "empty") << QString("") << QByteArray("");
1633
1634 add("Moebius");
1635 add(LONG_STRING_256);
1636}
1637
1638template <typename String>
1639void tst_QStringApiSymmetry::toLocal8Bit_impl()
1640{
1641 QFETCH(const QString, unicode);
1642 QFETCH(const QByteArray, local);
1643
1644 const auto str = make<String>(unicode);
1645
1646 const auto result = str.toLocal8Bit();
1647
1648 QCOMPARE(result, local);
1649 QCOMPARE(unicode.isEmpty(), result.isEmpty());
1650 QCOMPARE(unicode.isNull(), result.isNull());
1651}
1652
1653void tst_QStringApiSymmetry::toLatin1_data()
1654{
1655 QTest::addColumn<QString>(name: "unicode");
1656 QTest::addColumn<QByteArray>(name: "latin1");
1657
1658 auto add = [](const char *l1) {
1659 const QByteArray ba(l1);
1660 QString s;
1661 for (char c : ba)
1662 s += QLatin1Char(c);
1663 QTest::newRow(dataTag: rowName(data: ba).constData()) << s << ba;
1664 };
1665
1666 QTest::addRow(format: "null") << QString() << QByteArray();
1667 QTest::addRow(format: "empty") << QString("") << QByteArray("");
1668
1669 add("M\xF6" "bius");
1670 add(LONG_STRING_256);
1671}
1672
1673template <typename String>
1674void tst_QStringApiSymmetry::toLatin1_impl()
1675{
1676 QFETCH(const QString, unicode);
1677 QFETCH(const QByteArray, latin1);
1678
1679 const auto str = make<String>(unicode);
1680
1681 const auto result = str.toLatin1();
1682
1683 QCOMPARE(result, latin1);
1684 QCOMPARE(unicode.isEmpty(), result.isEmpty());
1685 QCOMPARE(unicode.isNull(), result.isNull());
1686}
1687
1688void tst_QStringApiSymmetry::toUtf8_data()
1689{
1690 QTest::addColumn<QString>(name: "unicode");
1691 QTest::addColumn<QByteArray>(name: "utf8");
1692
1693 auto add = [](const char *u8) {
1694 QByteArray ba(u8);
1695 QString s = ba;
1696 QTest::newRow(dataTag: rowName(data: ba).constData()) << s << ba;
1697 };
1698
1699 QTest::addRow(format: "null") << QString() << QByteArray();
1700 QTest::addRow(format: "empty") << QString("") << QByteArray("");
1701
1702 add("M\xC3\xB6" "bius");
1703 add(LONG_STRING_256);
1704}
1705
1706template <typename String>
1707void tst_QStringApiSymmetry::toUtf8_impl()
1708{
1709 QFETCH(const QString, unicode);
1710 QFETCH(const QByteArray, utf8);
1711
1712 const auto str = make<String>(unicode);
1713
1714 const auto result = str.toUtf8();
1715
1716 QCOMPARE(result, utf8);
1717 QCOMPARE(unicode.isEmpty(), result.isEmpty());
1718 QCOMPARE(unicode.isNull(), result.isNull());
1719}
1720
1721void tst_QStringApiSymmetry::toUcs4_data()
1722{
1723 QTest::addColumn<QString>(name: "unicode");
1724 QTest::addColumn<QVector<uint>>(name: "ucs4");
1725
1726 auto add = [](const char *l1) {
1727 const QByteArray ba(l1);
1728 QString s;
1729 QVector<uint> ucs4;
1730 for (char c : ba) {
1731 s += QLatin1Char(c);
1732 ucs4.append(t: uint(uchar(c)));
1733 }
1734 QTest::newRow(dataTag: rowName(data: ba).constData()) << s << ucs4;
1735 };
1736
1737 QTest::addRow(format: "null") << QString() << QVector<uint>();
1738 QTest::addRow(format: "empty") << QString("") << QVector<uint>();
1739
1740 add("M\xF6" "bius");
1741 add(LONG_STRING_256);
1742}
1743
1744template <typename String>
1745void tst_QStringApiSymmetry::toUcs4_impl()
1746{
1747 QFETCH(const QString, unicode);
1748 QFETCH(const QVector<uint>, ucs4);
1749
1750 const auto str = make<String>(unicode);
1751
1752 const auto result = str.toUcs4();
1753
1754 QCOMPARE(result, ucs4);
1755 QCOMPARE(unicode.isEmpty(), ucs4.isEmpty());
1756}
1757
1758void tst_QStringApiSymmetry::indexOf_data(bool rhsHasVariableLength)
1759{
1760 QTest::addColumn<QString>(name: "haystackU16");
1761 QTest::addColumn<QLatin1String>(name: "haystackL1");
1762 QTest::addColumn<QString>(name: "needleU16");
1763 QTest::addColumn<QLatin1String>(name: "needleL1");
1764 QTest::addColumn<qsizetype>(name: "startpos");
1765 QTest::addColumn<qsizetype>(name: "resultCS");
1766 QTest::addColumn<qsizetype>(name: "resultCIS");
1767
1768 constexpr qsizetype zeroPos = 0;
1769 constexpr qsizetype minus1Pos = -1;
1770
1771 if (rhsHasVariableLength) {
1772 QTest::addRow(format: "haystack: null, needle: null") << null << QLatin1String()
1773 << null << QLatin1String() << zeroPos << zeroPos << zeroPos;
1774 QTest::addRow(format: "haystack: empty, needle: null") << empty << QLatin1String("")
1775 << null << QLatin1String() << zeroPos << zeroPos << zeroPos;
1776 QTest::addRow(format: "haystack: a, needle: null") << a << QLatin1String("a")
1777 << null << QLatin1String() << zeroPos << zeroPos << zeroPos;
1778 QTest::addRow(format: "haystack: null, needle: empty") << null << QLatin1String()
1779 << empty << QLatin1String("") << zeroPos << zeroPos << zeroPos;
1780 QTest::addRow(format: "haystack: a, needle: empty") << a << QLatin1String("a")
1781 << empty << QLatin1String("") << zeroPos << zeroPos << zeroPos;
1782 QTest::addRow(format: "haystack: empty, needle: empty") << empty << QLatin1String("")
1783 << empty << QLatin1String("") << zeroPos << zeroPos << zeroPos;
1784 }
1785 QTest::addRow(format: "haystack: empty, needle: a") << empty << QLatin1String("")
1786 << a << QLatin1String("a") << zeroPos << minus1Pos << minus1Pos;
1787 QTest::addRow(format: "haystack: null, needle: a") << null << QLatin1String()
1788 << a << QLatin1String("a") << zeroPos << minus1Pos << minus1Pos;
1789
1790
1791#define ROW(h, n, st, cs, cis) \
1792 QTest::addRow("haystack: %s, needle: %s", #h, #n) << h << QLatin1String(#h) \
1793 << n << QLatin1String(#n) \
1794 << qsizetype(st) << qsizetype(cs) << qsizetype(cis)
1795
1796 ROW(abc, a, 0, 0, 0);
1797 ROW(abc, A, 0, -1, 0);
1798 ROW(abc, a, 1, -1, -1);
1799 ROW(abc, A, 1, -1, -1);
1800 ROW(abc, b, 0, 1, 1);
1801 ROW(abc, B, 0, -1, 1);
1802 ROW(abc, b, 1, 1, 1);
1803 ROW(abc, B, 1, -1, 1);
1804 ROW(abc, B, 2, -1, -1);
1805
1806 ROW(ABC, A, 0, 0, 0);
1807 ROW(ABC, a, 0, -1, 0);
1808 ROW(ABC, A, 1, -1, -1);
1809 ROW(ABC, a, 1, -1, -1);
1810 ROW(ABC, B, 0, 1, 1);
1811 ROW(ABC, b, 0, -1, 1);
1812 ROW(ABC, B, 1, 1, 1);
1813 ROW(ABC, b, 1, -1, 1);
1814 ROW(ABC, B, 2, -1, -1);
1815
1816 if (rhsHasVariableLength) {
1817 ROW(aBc, bc, 0, -1, 1);
1818 ROW(aBc, Bc, 0, 1, 1);
1819 ROW(aBc, bC, 0, -1, 1);
1820 ROW(aBc, BC, 0, -1, 1);
1821
1822 ROW(AbC, bc, 0, -1, 1);
1823 ROW(AbC, Bc, 0, -1, 1);
1824 ROW(AbC, bC, 0, 1, 1);
1825 ROW(AbC, BC, 0, -1, 1);
1826 ROW(AbC, BC, 1, -1, 1);
1827 ROW(AbC, BC, 2, -1, -1);
1828 }
1829#undef ROW
1830
1831}
1832
1833template <typename Haystack, typename Needle>
1834void tst_QStringApiSymmetry::indexOf_impl() const
1835{
1836 QFETCH(const QString, haystackU16);
1837 QFETCH(const QLatin1String, haystackL1);
1838 QFETCH(const QString, needleU16);
1839 QFETCH(const QLatin1String, needleL1);
1840 QFETCH(const qsizetype, startpos);
1841 QFETCH(const qsizetype, resultCS);
1842 QFETCH(const qsizetype, resultCIS);
1843
1844 const auto haystackU8 = haystackU16.toUtf8();
1845 const auto needleU8 = needleU16.toUtf8();
1846
1847 const auto haystack = make<Haystack>(QStringRef(&haystackU16), haystackL1, haystackU8);
1848 const auto needle = make<Needle>(QStringRef(&needleU16), needleL1, needleU8);
1849
1850 using size_type = typename Haystack::size_type;
1851
1852 QCOMPARE(haystack.indexOf(needle, startpos), size_type(resultCS));
1853 QCOMPARE(haystack.indexOf(needle, startpos, Qt::CaseSensitive), size_type(resultCS));
1854 QCOMPARE(haystack.indexOf(needle, startpos, Qt::CaseInsensitive), size_type(resultCIS));
1855}
1856
1857static QString ABCDEFGHIEfGEFG = QStringLiteral("ABCDEFGHIEfGEFG");
1858static QString EFG = QStringLiteral("EFG");
1859static QString efg = QStringLiteral("efg");
1860static QString asd = QStringLiteral("asd");
1861static QString asdf = QStringLiteral("asdf");
1862static QString Z = QStringLiteral("Z");
1863
1864void tst_QStringApiSymmetry::contains_data(bool rhsHasVariableLength)
1865{
1866 QTest::addColumn<QString>(name: "haystackU16");
1867 QTest::addColumn<QLatin1String>(name: "haystackL1");
1868 QTest::addColumn<QString>(name: "needleU16");
1869 QTest::addColumn<QLatin1String>(name: "needleL1");
1870 QTest::addColumn<bool>(name: "resultCS");
1871 QTest::addColumn<bool>(name: "resultCIS");
1872
1873 if (rhsHasVariableLength) {
1874 QTest::addRow(format: "haystack: null, needle: null") << null << QLatin1String()
1875 << null << QLatin1String() << true << true;
1876 QTest::addRow(format: "haystack: empty, needle: null") << empty << QLatin1String("")
1877 << null << QLatin1String() << true << true;
1878 QTest::addRow(format: "haystack: a, needle: null") << a << QLatin1String("a")
1879 << null << QLatin1String() << true << true;
1880 QTest::addRow(format: "haystack: null, needle: empty") << null << QLatin1String()
1881 << empty << QLatin1String("") << true << true;
1882 QTest::addRow(format: "haystack: a, needle: empty") << a << QLatin1String("a")
1883 << empty << QLatin1String("") << true << true;;
1884 QTest::addRow(format: "haystack: empty, needle: empty") << empty << QLatin1String("")
1885 << empty << QLatin1String("") << true << true;
1886 }
1887 QTest::addRow(format: "haystack: empty, needle: a") << empty << QLatin1String("")
1888 << a << QLatin1String("a") << false << false;
1889 QTest::addRow(format: "haystack: null, needle: a") << null << QLatin1String()
1890 << a << QLatin1String("a") << false << false;
1891
1892#define ROW(h, n, cs, cis) \
1893 QTest::addRow("haystack: %s, needle: %s", #h, #n) << h << QLatin1String(#h) \
1894 << n << QLatin1String(#n) \
1895 << cs << cis
1896
1897 ROW(ABCDEFGHIEfGEFG, A, true, true);
1898 ROW(ABCDEFGHIEfGEFG, a, false, true);
1899 ROW(ABCDEFGHIEfGEFG, Z, false, false);
1900 if (rhsHasVariableLength) {
1901 ROW(ABCDEFGHIEfGEFG, EFG, true, true);
1902 ROW(ABCDEFGHIEfGEFG, efg, false, true);
1903 }
1904 ROW(ABCDEFGHIEfGEFG, E, true, true);
1905 ROW(ABCDEFGHIEfGEFG, e, false, true);
1906#undef ROW
1907}
1908
1909template <typename Haystack, typename Needle>
1910void tst_QStringApiSymmetry::contains_impl() const
1911{
1912 QFETCH(const QString, haystackU16);
1913 QFETCH(const QLatin1String, haystackL1);
1914 QFETCH(const QString, needleU16);
1915 QFETCH(const QLatin1String, needleL1);
1916 QFETCH(const bool, resultCS);
1917 QFETCH(const bool, resultCIS);
1918
1919 const auto haystackU8 = haystackU16.toUtf8();
1920 const auto needleU8 = needleU16.toUtf8();
1921
1922 const auto haystack = make<Haystack>(QStringRef(&haystackU16), haystackL1, haystackU8);
1923 const auto needle = make<Needle>(QStringRef(&needleU16), needleL1, needleU8);
1924
1925 QCOMPARE(haystack.contains(needle), resultCS);
1926 QCOMPARE(haystack.contains(needle, Qt::CaseSensitive), resultCS);
1927 QCOMPARE(haystack.contains(needle, Qt::CaseInsensitive), resultCIS);
1928}
1929
1930void tst_QStringApiSymmetry::lastIndexOf_data(bool rhsHasVariableLength)
1931{
1932 QTest::addColumn<QString>(name: "haystackU16");
1933 QTest::addColumn<QLatin1String>(name: "haystackL1");
1934 QTest::addColumn<QString>(name: "needleU16");
1935 QTest::addColumn<QLatin1String>(name: "needleL1");
1936 QTest::addColumn<qsizetype>(name: "startpos");
1937 QTest::addColumn<qsizetype>(name: "resultCS");
1938 QTest::addColumn<qsizetype>(name: "resultCIS");
1939
1940 constexpr qsizetype zeroPos = 0;
1941 constexpr qsizetype minus1Pos = -1;
1942
1943 if (rhsHasVariableLength) {
1944 QTest::addRow(format: "haystack: null, needle: null") << null << QLatin1String()
1945 << null << QLatin1String() << minus1Pos << minus1Pos << minus1Pos;
1946 QTest::addRow(format: "haystack: empty, needle: null") << empty << QLatin1String("")
1947 << null << QLatin1String() << minus1Pos << minus1Pos << minus1Pos;
1948 QTest::addRow(format: "haystack: a, needle: null") << a << QLatin1String("a")
1949 << null << QLatin1String() << minus1Pos << zeroPos << zeroPos;
1950 QTest::addRow(format: "haystack: null, needle: empty") << null << QLatin1String()
1951 << empty << QLatin1String("") << minus1Pos << minus1Pos << minus1Pos;
1952 QTest::addRow(format: "haystack: a, needle: empty") << a << QLatin1String("a")
1953 << empty << QLatin1String("") << minus1Pos << zeroPos << zeroPos;
1954 QTest::addRow(format: "haystack: empty, needle: empty") << empty << QLatin1String("")
1955 << empty << QLatin1String("") << minus1Pos << minus1Pos << minus1Pos;
1956 }
1957 QTest::addRow(format: "haystack: empty, needle: a") << empty << QLatin1String("")
1958 << a << QLatin1String("a") << minus1Pos << minus1Pos << minus1Pos;
1959 QTest::addRow(format: "haystack: null, needle: a") << null << QLatin1String()
1960 << a << QLatin1String("a") << minus1Pos << minus1Pos << minus1Pos;
1961
1962 if (rhsHasVariableLength) {
1963 QTest::addRow(format: "haystack: a, needle: null") << a << QLatin1String("a")
1964 << null << QLatin1String() << qsizetype(1) << qsizetype(1) << qsizetype(1);
1965 QTest::addRow(format: "haystack: a, needle: empty") << a << QLatin1String("a")
1966 << empty << QLatin1String("") << qsizetype(1) << qsizetype(1) << qsizetype(1);
1967 QTest::addRow(format: "haystack: a, needle: null") << a << QLatin1String("a")
1968 << null << QLatin1String() << qsizetype(2) << minus1Pos << minus1Pos;
1969 QTest::addRow(format: "haystack: a, needle: empty") << a << QLatin1String("a")
1970 << empty << QLatin1String("") << qsizetype(2) << minus1Pos << minus1Pos;
1971 }
1972
1973#define ROW(h, n, st, cs, cis) \
1974 QTest::addRow("haystack: %s, needle: %s", #h, #n) << h << QLatin1String(#h) \
1975 << n << QLatin1String(#n) \
1976 << qsizetype(st) << qsizetype(cs) << qsizetype(cis)
1977
1978 if (rhsHasVariableLength)
1979 ROW(asd, asdf, -1, -1, -1);
1980
1981 ROW(ABCDEFGHIEfGEFG, G, -1, 14, 14);
1982 ROW(ABCDEFGHIEfGEFG, g, -1, -1, 14);
1983 ROW(ABCDEFGHIEfGEFG, G, -3, 11, 11);
1984 ROW(ABCDEFGHIEfGEFG, g, -3, -1, 11);
1985 ROW(ABCDEFGHIEfGEFG, G, -5, 6, 6);
1986 ROW(ABCDEFGHIEfGEFG, g, -5, -1, 6);
1987 ROW(ABCDEFGHIEfGEFG, G, 14, 14, 14);
1988 ROW(ABCDEFGHIEfGEFG, g, 14, -1, 14);
1989 ROW(ABCDEFGHIEfGEFG, G, 13, 11, 11);
1990 ROW(ABCDEFGHIEfGEFG, g, 13, -1, 11);
1991 ROW(ABCDEFGHIEfGEFG, G, 15, -1, -1);
1992 ROW(ABCDEFGHIEfGEFG, g, 15, -1, -1);
1993 ROW(ABCDEFGHIEfGEFG, B, 14, 1, 1);
1994 ROW(ABCDEFGHIEfGEFG, b, 14, -1, 1);
1995 ROW(ABCDEFGHIEfGEFG, B, -1, 1, 1);
1996 ROW(ABCDEFGHIEfGEFG, b, -1, -1, 1);
1997 ROW(ABCDEFGHIEfGEFG, B, 1, 1, 1);
1998 ROW(ABCDEFGHIEfGEFG, b, 1, -1, 1);
1999 ROW(ABCDEFGHIEfGEFG, B, 0, -1, -1);
2000 ROW(ABCDEFGHIEfGEFG, b, 0, -1, -1);
2001 ROW(ABCDEFGHIEfGEFG, A, 0, 0, 0);
2002 ROW(ABCDEFGHIEfGEFG, a, 0, -1, 0);
2003 ROW(ABCDEFGHIEfGEFG, A, -15, 0, 0);
2004 ROW(ABCDEFGHIEfGEFG, a, -15, -1, 0);
2005
2006 if (rhsHasVariableLength) {
2007 ROW(ABCDEFGHIEfGEFG, efg, 0, -1, -1);
2008 ROW(ABCDEFGHIEfGEFG, efg, 15, -1, -1);
2009 ROW(ABCDEFGHIEfGEFG, efg, -15, -1, -1);
2010 ROW(ABCDEFGHIEfGEFG, efg, 14, -1, 12);
2011 ROW(ABCDEFGHIEfGEFG, efg, 12, -1, 12);
2012 ROW(ABCDEFGHIEfGEFG, efg, -12, -1, -1);
2013 ROW(ABCDEFGHIEfGEFG, efg, 11, -1, 9);
2014 }
2015#undef ROW
2016}
2017
2018template <typename Haystack, typename Needle>
2019void tst_QStringApiSymmetry::lastIndexOf_impl() const
2020{
2021 QFETCH(const QString, haystackU16);
2022 QFETCH(const QLatin1String, haystackL1);
2023 QFETCH(const QString, needleU16);
2024 QFETCH(const QLatin1String, needleL1);
2025 QFETCH(const qsizetype, startpos);
2026 QFETCH(const qsizetype, resultCS);
2027 QFETCH(const qsizetype, resultCIS);
2028
2029 const auto haystackU8 = haystackU16.toUtf8();
2030 const auto needleU8 = needleU16.toUtf8();
2031
2032 const auto haystack = make<Haystack>(QStringRef(&haystackU16), haystackL1, haystackU8);
2033 const auto needle = make<Needle>(QStringRef(&needleU16), needleL1, needleU8);
2034
2035 using size_type = typename Haystack::size_type;
2036
2037 QCOMPARE(haystack.lastIndexOf(needle, startpos), size_type(resultCS));
2038 QCOMPARE(haystack.lastIndexOf(needle, startpos, Qt::CaseSensitive), size_type(resultCS));
2039 QCOMPARE(haystack.lastIndexOf(needle, startpos, Qt::CaseInsensitive), size_type(resultCIS));
2040
2041}
2042
2043QTEST_APPLESS_MAIN(tst_QStringApiSymmetry)
2044
2045#include "tst_qstringapisymmetry.moc"
2046

source code of qtbase/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp