1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | |
30 | #include <QtTest/QtTest> |
31 | |
32 | #include <QPair> |
33 | #include <QTextCodec> |
34 | #include <QSysInfo> |
35 | #include <QLatin1String> |
36 | |
37 | class tst_QGlobal: public QObject |
38 | { |
39 | Q_OBJECT |
40 | |
41 | private slots: |
42 | void cMode(); |
43 | void qIsNull(); |
44 | void for_each(); |
45 | void qassert(); |
46 | void qtry(); |
47 | void checkptr(); |
48 | void qstaticassert(); |
49 | void qConstructorFunction(); |
50 | void qCoreAppStartupFunction(); |
51 | void qCoreAppStartupFunctionRestart(); |
52 | void qAlignOf(); |
53 | void integerForSize(); |
54 | void qprintable(); |
55 | void qprintable_data(); |
56 | void buildAbiEndianness(); |
57 | void testqOverload(); |
58 | }; |
59 | |
60 | extern "C" { // functions in qglobal.c |
61 | void tst_GlobalTypes(); |
62 | int tst_QtVersion(); |
63 | const char *tst_qVersion(); |
64 | } |
65 | |
66 | void tst_QGlobal::cMode() |
67 | { |
68 | tst_GlobalTypes(); |
69 | QCOMPARE(tst_QtVersion(), QT_VERSION); |
70 | |
71 | #ifndef QT_NAMESPACE |
72 | QCOMPARE(tst_qVersion(), qVersion()); |
73 | #endif |
74 | } |
75 | |
76 | void tst_QGlobal::qIsNull() |
77 | { |
78 | double d = 0.0; |
79 | float f = 0.0f; |
80 | |
81 | QVERIFY(::qIsNull(d)); |
82 | QVERIFY(::qIsNull(f)); |
83 | |
84 | d += 0.000000001; |
85 | f += 0.0000001f; |
86 | |
87 | QVERIFY(!::qIsNull(d)); |
88 | QVERIFY(!::qIsNull(f)); |
89 | |
90 | d = -0.0; |
91 | f = -0.0f; |
92 | |
93 | QVERIFY(::qIsNull(d)); |
94 | QVERIFY(::qIsNull(f)); |
95 | } |
96 | |
97 | void tst_QGlobal::for_each() |
98 | { |
99 | QVector<int> list; |
100 | list << 0 << 1 << 2 << 3 << 4 << 5; |
101 | |
102 | int counter = 0; |
103 | foreach(int i, list) { |
104 | QCOMPARE(i, counter++); |
105 | } |
106 | QCOMPARE(counter, list.count()); |
107 | |
108 | // do it again, to make sure we don't have any for-scoping |
109 | // problems with older compilers |
110 | counter = 0; |
111 | foreach(int i, list) { |
112 | QCOMPARE(i, counter++); |
113 | } |
114 | QCOMPARE(counter, list.count()); |
115 | |
116 | // check whether we can pass a constructor as container argument |
117 | counter = 0; |
118 | foreach (int i, QVector<int>(list)) { |
119 | QCOMPARE(i, counter++); |
120 | } |
121 | QCOMPARE(counter, list.count()); |
122 | |
123 | // check whether we can use a lambda |
124 | counter = 0; |
125 | foreach (int i, [&](){ return list; }()) { |
126 | QCOMPARE(i, counter++); |
127 | } |
128 | QCOMPARE(counter, list.count()); |
129 | |
130 | // Should also work with an existing variable |
131 | int local; |
132 | counter = 0; |
133 | foreach (local, list) { |
134 | QCOMPARE(local, counter++); |
135 | } |
136 | QCOMPARE(counter, list.count()); |
137 | QCOMPARE(local, counter - 1); |
138 | |
139 | // Test the macro does not mess if/else conditions |
140 | counter = 0; |
141 | if (true) |
142 | foreach (int i, list) |
143 | QCOMPARE(i, counter++); |
144 | else |
145 | QFAIL("If/Else mismatch" ); |
146 | QCOMPARE(counter, list.count()); |
147 | |
148 | counter = 0; |
149 | if (false) |
150 | foreach (int i, list) |
151 | if (i) QFAIL("If/Else mismatch" ); |
152 | else QFAIL("If/Else mismatch" ); |
153 | else |
154 | foreach (int i, list) |
155 | if (false) { } |
156 | else QCOMPARE(i, counter++); |
157 | QCOMPARE(counter, list.count()); |
158 | |
159 | // break and continue |
160 | counter = 0; |
161 | foreach (int i, list) { |
162 | if (i == 0) |
163 | continue; |
164 | QCOMPARE(i, (counter++) + 1); |
165 | if (i == 3) |
166 | break; |
167 | } |
168 | QCOMPARE(counter, 3); |
169 | } |
170 | |
171 | void tst_QGlobal::qassert() |
172 | { |
173 | bool passed = false; |
174 | if (false) { |
175 | Q_ASSERT(false); |
176 | } else { |
177 | passed = true; |
178 | } |
179 | QVERIFY(passed); |
180 | |
181 | passed = false; |
182 | if (false) { |
183 | Q_ASSERT_X(false, "tst_QGlobal" , "qassert" ); |
184 | } else { |
185 | passed = true; |
186 | } |
187 | QVERIFY(passed); |
188 | |
189 | passed = false; |
190 | if (false) |
191 | Q_ASSERT(false); |
192 | else |
193 | passed = true; |
194 | QVERIFY(passed); |
195 | |
196 | passed = false; |
197 | if (false) |
198 | Q_ASSERT_X(false, "tst_QGlobal" , "qassert" ); |
199 | else |
200 | passed = true; |
201 | QVERIFY(passed); |
202 | } |
203 | |
204 | void tst_QGlobal::qtry() |
205 | { |
206 | int i = 0; |
207 | QT_TRY { |
208 | i = 1; |
209 | QT_THROW(42); |
210 | i = 2; |
211 | } QT_CATCH(int) { |
212 | QCOMPARE(i, 1); |
213 | i = 7; |
214 | } |
215 | #ifdef QT_NO_EXCEPTIONS |
216 | QCOMPARE(i, 2); |
217 | #else |
218 | QCOMPARE(i, 7); |
219 | #endif |
220 | |
221 | // check propper if/else scoping |
222 | i = 0; |
223 | if (true) { |
224 | QT_TRY { |
225 | i = 2; |
226 | QT_THROW(42); |
227 | i = 4; |
228 | } QT_CATCH(int) { |
229 | QCOMPARE(i, 2); |
230 | i = 4; |
231 | } |
232 | } else { |
233 | QCOMPARE(i, 0); |
234 | } |
235 | QCOMPARE(i, 4); |
236 | |
237 | i = 0; |
238 | if (false) { |
239 | QT_TRY { |
240 | i = 2; |
241 | QT_THROW(42); |
242 | i = 4; |
243 | } QT_CATCH(int) { |
244 | QCOMPARE(i, 2); |
245 | i = 2; |
246 | } |
247 | } else { |
248 | i = 8; |
249 | } |
250 | QCOMPARE(i, 8); |
251 | |
252 | i = 0; |
253 | if (false) { |
254 | i = 42; |
255 | } else { |
256 | QT_TRY { |
257 | i = 2; |
258 | QT_THROW(42); |
259 | i = 4; |
260 | } QT_CATCH(int) { |
261 | QCOMPARE(i, 2); |
262 | i = 4; |
263 | } |
264 | } |
265 | QCOMPARE(i, 4); |
266 | } |
267 | |
268 | void tst_QGlobal::checkptr() |
269 | { |
270 | int i; |
271 | QCOMPARE(q_check_ptr(&i), &i); |
272 | |
273 | const char *c = "hello" ; |
274 | QCOMPARE(q_check_ptr(c), c); |
275 | } |
276 | |
277 | // Check Q_STATIC_ASSERT, It should compile |
278 | // note that, we are not able to test Q_STATIC_ASSERT(false), to do it manually someone has |
279 | // to replace expressions (in the asserts) one by one to false, and check if it breaks build. |
280 | class MyTrue |
281 | { |
282 | public: |
283 | MyTrue() |
284 | { |
285 | Q_STATIC_ASSERT(true); |
286 | Q_STATIC_ASSERT(!false); |
287 | Q_STATIC_ASSERT_X(true,"" ); |
288 | Q_STATIC_ASSERT_X(!false,"" ); |
289 | } |
290 | ~MyTrue() |
291 | { |
292 | Q_STATIC_ASSERT(true); |
293 | Q_STATIC_ASSERT(!false); |
294 | Q_STATIC_ASSERT_X(true,"" ); |
295 | Q_STATIC_ASSERT_X(!false,"" ); |
296 | } |
297 | Q_STATIC_ASSERT(true); |
298 | Q_STATIC_ASSERT(!false); |
299 | Q_STATIC_ASSERT_X(true,"" ); |
300 | Q_STATIC_ASSERT_X(!false,"" ); |
301 | }; |
302 | |
303 | struct MyExpresion |
304 | { |
305 | void foo() |
306 | { |
307 | Q_STATIC_ASSERT(sizeof(MyTrue) > 0); |
308 | Q_STATIC_ASSERT(sizeof(MyTrue) > 0); |
309 | Q_STATIC_ASSERT_X(sizeof(MyTrue) > 0,"" ); |
310 | Q_STATIC_ASSERT_X(sizeof(MyTrue) > 0,"" ); |
311 | } |
312 | private: |
313 | Q_STATIC_ASSERT(sizeof(MyTrue) > 0); |
314 | Q_STATIC_ASSERT(sizeof(MyTrue) > 0); |
315 | Q_STATIC_ASSERT_X(sizeof(MyTrue) > 0, "" ); |
316 | Q_STATIC_ASSERT_X(sizeof(MyTrue) > 0, "" ); |
317 | }; |
318 | |
319 | struct TypeDef |
320 | { |
321 | typedef int T; |
322 | Q_STATIC_ASSERT(sizeof(T)); |
323 | Q_STATIC_ASSERT_X(sizeof(T), "" ); |
324 | }; |
325 | |
326 | template<typename T1, typename T2> |
327 | struct Template |
328 | { |
329 | static const bool True = true; |
330 | typedef typename T1::T DependentType; |
331 | Q_STATIC_ASSERT(True); |
332 | Q_STATIC_ASSERT(!!True); |
333 | Q_STATIC_ASSERT(sizeof(DependentType)); |
334 | Q_STATIC_ASSERT(!!sizeof(DependentType)); |
335 | Q_STATIC_ASSERT_X(True, "" ); |
336 | Q_STATIC_ASSERT_X(!!True, "" ); |
337 | Q_STATIC_ASSERT_X(sizeof(DependentType), "" ); |
338 | Q_STATIC_ASSERT_X(!!sizeof(DependentType), "" ); |
339 | }; |
340 | |
341 | struct MyTemplate |
342 | { |
343 | static const bool Value = Template<TypeDef, int>::True; |
344 | Q_STATIC_ASSERT(Value); |
345 | Q_STATIC_ASSERT(!!Value); |
346 | Q_STATIC_ASSERT_X(Value, "" ); |
347 | Q_STATIC_ASSERT_X(!!Value, "" ); |
348 | }; |
349 | |
350 | void tst_QGlobal::qstaticassert() |
351 | { |
352 | // Force compilation of these classes |
353 | MyTrue tmp1; |
354 | MyExpresion tmp2; |
355 | MyTemplate tmp3; |
356 | Q_UNUSED(tmp1); |
357 | Q_UNUSED(tmp2); |
358 | Q_UNUSED(tmp3); |
359 | #ifdef __COUNTER__ |
360 | // if the compiler supports __COUNTER__, multiple |
361 | // Q_STATIC_ASSERT's on a single line should compile: |
362 | Q_STATIC_ASSERT(true); Q_STATIC_ASSERT_X(!false, "" ); |
363 | #endif // __COUNTER__ |
364 | QVERIFY(true); // if the test compiles it has passed. |
365 | } |
366 | |
367 | static int qConstructorFunctionValue; |
368 | static void qConstructorFunctionCtor() |
369 | { |
370 | qConstructorFunctionValue = 123; |
371 | } |
372 | Q_CONSTRUCTOR_FUNCTION(qConstructorFunctionCtor); |
373 | |
374 | void tst_QGlobal::qConstructorFunction() |
375 | { |
376 | QCOMPARE(qConstructorFunctionValue, 123); |
377 | } |
378 | |
379 | static int qStartupFunctionValue; |
380 | static void myStartupFunc() |
381 | { |
382 | Q_ASSERT(QCoreApplication::instance()); |
383 | if (QCoreApplication::instance()) |
384 | qStartupFunctionValue += 124; |
385 | } |
386 | |
387 | Q_COREAPP_STARTUP_FUNCTION(myStartupFunc) |
388 | |
389 | void tst_QGlobal::qCoreAppStartupFunction() |
390 | { |
391 | QCOMPARE(qStartupFunctionValue, 0); |
392 | int argc = 1; |
393 | char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; |
394 | QCoreApplication app(argc, argv); |
395 | QCOMPARE(qStartupFunctionValue, 124); |
396 | } |
397 | |
398 | void tst_QGlobal::qCoreAppStartupFunctionRestart() |
399 | { |
400 | qStartupFunctionValue = 0; |
401 | qCoreAppStartupFunction(); |
402 | qStartupFunctionValue = 0; |
403 | qCoreAppStartupFunction(); |
404 | } |
405 | |
406 | struct isEnum_A { |
407 | int n_; |
408 | }; |
409 | |
410 | enum isEnum_B_Byte { isEnum_B_Byte_x = 63 }; |
411 | enum isEnum_B_Short { isEnum_B_Short_x = 1024 }; |
412 | enum isEnum_B_Int { isEnum_B_Int_x = 1 << 20 }; |
413 | |
414 | union isEnum_C {}; |
415 | |
416 | class isEnum_D { |
417 | public: |
418 | operator int() const; |
419 | }; |
420 | |
421 | class isEnum_E { |
422 | private: |
423 | operator int() const; |
424 | }; |
425 | |
426 | class isEnum_F { |
427 | public: |
428 | enum AnEnum {}; |
429 | }; |
430 | |
431 | struct Empty {}; |
432 | template <class T> struct AlignmentInStruct { T dummy; }; |
433 | |
434 | typedef int (*fun) (); |
435 | typedef int (Empty::*memFun) (); |
436 | |
437 | #define TEST_AlignOf(type, alignment) \ |
438 | do { \ |
439 | TEST_AlignOf_impl(type, alignment); \ |
440 | \ |
441 | TEST_AlignOf_impl(type &, alignment); \ |
442 | TEST_AlignOf_RValueRef(type &&, alignment); \ |
443 | \ |
444 | TEST_AlignOf_impl(type [5], alignment); \ |
445 | TEST_AlignOf_impl(type (&) [5], alignment); \ |
446 | \ |
447 | TEST_AlignOf_impl(AlignmentInStruct<type>, alignment); \ |
448 | \ |
449 | /* Some internal sanity validation, just for fun */ \ |
450 | TEST_AlignOf_impl(AlignmentInStruct<type [5]>, alignment); \ |
451 | TEST_AlignOf_impl(AlignmentInStruct<type &>, Q_ALIGNOF(void *)); \ |
452 | TEST_AlignOf_impl(AlignmentInStruct<type (&) [5]>, \ |
453 | Q_ALIGNOF(void *)); \ |
454 | TEST_AlignOf_RValueRef(AlignmentInStruct<type &&>, \ |
455 | Q_ALIGNOF(void *)); \ |
456 | } while (false) \ |
457 | /**/ |
458 | |
459 | #define TEST_AlignOf_RValueRef(type, alignment) \ |
460 | TEST_AlignOf_impl(type, alignment) |
461 | |
462 | #define TEST_AlignOf_impl(type, alignment) \ |
463 | do { \ |
464 | QCOMPARE(Q_ALIGNOF(type), size_t(alignment)); \ |
465 | /* Compare to native operator for compilers that support it, |
466 | otherwise... erm... check consistency! :-) */ \ |
467 | QCOMPARE(alignof(type), Q_ALIGNOF(type)); \ |
468 | } while (false) |
469 | /**/ |
470 | |
471 | void tst_QGlobal::qAlignOf() |
472 | { |
473 | // Built-in types, except 64-bit integers and double |
474 | TEST_AlignOf(char, 1); |
475 | TEST_AlignOf(signed char, 1); |
476 | TEST_AlignOf(unsigned char, 1); |
477 | TEST_AlignOf(qint8, 1); |
478 | TEST_AlignOf(quint8, 1); |
479 | TEST_AlignOf(qint16, 2); |
480 | TEST_AlignOf(quint16, 2); |
481 | TEST_AlignOf(qint32, 4); |
482 | TEST_AlignOf(quint32, 4); |
483 | TEST_AlignOf(void *, sizeof(void *)); |
484 | |
485 | // Depends on platform and compiler, disabling test for now |
486 | // TEST_AlignOf(long double, 16); |
487 | |
488 | // Empty struct |
489 | TEST_AlignOf(Empty, 1); |
490 | |
491 | // Function pointers |
492 | TEST_AlignOf(fun, Q_ALIGNOF(void *)); |
493 | TEST_AlignOf(memFun, Q_ALIGNOF(void *)); |
494 | |
495 | |
496 | // 64-bit integers and double |
497 | TEST_AlignOf_impl(qint64, 8); |
498 | TEST_AlignOf_impl(quint64, 8); |
499 | TEST_AlignOf_impl(double, 8); |
500 | |
501 | TEST_AlignOf_impl(qint64 &, 8); |
502 | TEST_AlignOf_impl(quint64 &, 8); |
503 | TEST_AlignOf_impl(double &, 8); |
504 | |
505 | TEST_AlignOf_RValueRef(qint64 &&, 8); |
506 | TEST_AlignOf_RValueRef(quint64 &&, 8); |
507 | TEST_AlignOf_RValueRef(double &&, 8); |
508 | |
509 | // 32-bit x86 ABI idiosyncrasies |
510 | #if defined(Q_PROCESSOR_X86_32) && !defined(Q_OS_WIN) |
511 | TEST_AlignOf_impl(AlignmentInStruct<qint64>, 4); |
512 | #else |
513 | TEST_AlignOf_impl(AlignmentInStruct<qint64>, 8); |
514 | #endif |
515 | |
516 | TEST_AlignOf_impl(AlignmentInStruct<quint64>, Q_ALIGNOF(AlignmentInStruct<qint64>)); |
517 | TEST_AlignOf_impl(AlignmentInStruct<double>, Q_ALIGNOF(AlignmentInStruct<qint64>)); |
518 | |
519 | // 32-bit x86 ABI, Clang disagrees with gcc |
520 | #if !defined(Q_PROCESSOR_X86_32) || !defined(Q_CC_CLANG) || defined(Q_OS_ANDROID) |
521 | TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(qint64)); |
522 | #else |
523 | TEST_AlignOf_impl(qint64 [5], Q_ALIGNOF(AlignmentInStruct<qint64>)); |
524 | #endif |
525 | |
526 | TEST_AlignOf_impl(qint64 (&) [5], Q_ALIGNOF(qint64 [5])); |
527 | TEST_AlignOf_impl(quint64 [5], Q_ALIGNOF(quint64 [5])); |
528 | TEST_AlignOf_impl(quint64 (&) [5], Q_ALIGNOF(quint64 [5])); |
529 | TEST_AlignOf_impl(double [5], Q_ALIGNOF(double [5])); |
530 | TEST_AlignOf_impl(double (&) [5], Q_ALIGNOF(double [5])); |
531 | } |
532 | |
533 | #undef TEST_AlignOf |
534 | #undef TEST_AlignOf_RValueRef |
535 | #undef TEST_AlignOf_impl |
536 | |
537 | void tst_QGlobal::integerForSize() |
538 | { |
539 | // compile-only test: |
540 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<1>::Signed) == 1); |
541 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<2>::Signed) == 2); |
542 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<4>::Signed) == 4); |
543 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<8>::Signed) == 8); |
544 | |
545 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<1>::Unsigned) == 1); |
546 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<2>::Unsigned) == 2); |
547 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<4>::Unsigned) == 4); |
548 | Q_STATIC_ASSERT(sizeof(QIntegerForSize<8>::Unsigned) == 8); |
549 | } |
550 | |
551 | typedef QPair<const char *, const char *> stringpair; |
552 | Q_DECLARE_METATYPE(stringpair) |
553 | |
554 | void tst_QGlobal::qprintable() |
555 | { |
556 | QFETCH(QVector<stringpair>, localestrings); |
557 | QFETCH(int, utf8index); |
558 | |
559 | QVERIFY(utf8index >= 0 && utf8index < localestrings.count()); |
560 | if (utf8index < 0 || utf8index >= localestrings.count()) |
561 | return; |
562 | |
563 | const char *const utf8string = localestrings.at(i: utf8index).second; |
564 | |
565 | QString string = QString::fromUtf8(str: utf8string); |
566 | |
567 | for (const stringpair &pair : qAsConst(t&: localestrings)) { |
568 | QTextCodec *codec = QTextCodec::codecForName(name: pair.first); |
569 | if (!codec) |
570 | continue; |
571 | QTextCodec::setCodecForLocale(codec); |
572 | // test qPrintable() |
573 | QVERIFY(qstrcmp(qPrintable(string), pair.second) == 0); |
574 | for (const stringpair &pair2 : qAsConst(t&: localestrings)) { |
575 | if (pair2.second == pair.second) |
576 | continue; |
577 | QVERIFY(qstrcmp(qPrintable(string), pair2.second) != 0); |
578 | } |
579 | // test qUtf8Printable() |
580 | QVERIFY(qstrcmp(qUtf8Printable(string), utf8string) == 0); |
581 | for (const stringpair &pair2 : qAsConst(t&: localestrings)) { |
582 | if (qstrcmp(str1: pair2.second, str2: utf8string) == 0) |
583 | continue; |
584 | QVERIFY(qstrcmp(qUtf8Printable(string), pair2.second) != 0); |
585 | } |
586 | } |
587 | |
588 | QTextCodec::setCodecForLocale(0); |
589 | } |
590 | |
591 | void tst_QGlobal::qprintable_data() |
592 | { |
593 | QTest::addColumn<QVector<stringpair> >(name: "localestrings" ); |
594 | QTest::addColumn<int>(name: "utf8index" ); // index of utf8 string |
595 | |
596 | // Unicode: HIRAGANA LETTER A, I, U, E, O (U+3442, U+3444, U+3446, U+3448, U+344a) |
597 | static const char *const utf8string = "\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a" ; |
598 | static const char *const eucjpstring = "\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa" ; |
599 | static const char *const sjisstring = "\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8" ; |
600 | |
601 | QVector<stringpair> japanesestrings; |
602 | japanesestrings << stringpair("UTF-8" , utf8string) |
603 | << stringpair("EUC-JP" , eucjpstring) |
604 | << stringpair("Shift_JIS" , sjisstring); |
605 | |
606 | QTest::newRow(dataTag: "Japanese" ) << japanesestrings << 0; |
607 | |
608 | } |
609 | |
610 | void tst_QGlobal::buildAbiEndianness() |
611 | { |
612 | #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN |
613 | QLatin1String endian("little_endian" ); |
614 | #elif Q_BYTE_ORDER == Q_BIG_ENDIAN |
615 | QLatin1String endian("big_endian" ); |
616 | #endif |
617 | QVERIFY(QSysInfo::buildAbi().contains(endian)); |
618 | } |
619 | |
620 | struct Overloaded |
621 | { |
622 | void foo() {} |
623 | void foo(QByteArray) {} |
624 | void foo(QByteArray, const QString &) {} |
625 | |
626 | void constFoo() const {} |
627 | void constFoo(QByteArray) const {} |
628 | void constFoo(QByteArray, const QString &) const {} |
629 | |
630 | void mixedFoo() {} |
631 | void mixedFoo(QByteArray) const {} |
632 | }; |
633 | |
634 | void freeOverloaded() {} |
635 | void freeOverloaded(QByteArray) {} |
636 | void freeOverloaded(QByteArray, const QString &) {} |
637 | |
638 | void freeOverloadedGet(QByteArray) {} |
639 | QByteArray freeOverloadedGet() { return QByteArray(); } |
640 | |
641 | |
642 | void tst_QGlobal::testqOverload() |
643 | { |
644 | #ifdef Q_COMPILER_VARIADIC_TEMPLATES |
645 | |
646 | // void returning free overloaded functions |
647 | QVERIFY(QOverload<>::of(&freeOverloaded) == |
648 | static_cast<void (*)()>(&freeOverloaded)); |
649 | |
650 | QVERIFY(QOverload<QByteArray>::of(&freeOverloaded) == |
651 | static_cast<void (*)(QByteArray)>(&freeOverloaded)); |
652 | |
653 | QVERIFY((QOverload<QByteArray, const QString &>::of(&freeOverloaded)) == |
654 | static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded)); |
655 | |
656 | // value returning free overloaded functions |
657 | QVERIFY(QOverload<>::of(&freeOverloadedGet) == |
658 | static_cast<QByteArray (*)()>(&freeOverloadedGet)); |
659 | |
660 | QVERIFY(QOverload<QByteArray>::of(&freeOverloadedGet) == |
661 | static_cast<void (*)(QByteArray)>(&freeOverloadedGet)); |
662 | |
663 | // void returning overloaded member functions |
664 | QVERIFY(QOverload<>::of(&Overloaded::foo) == |
665 | static_cast<void (Overloaded::*)()>(&Overloaded::foo)); |
666 | |
667 | QVERIFY(QOverload<QByteArray>::of(&Overloaded::foo) == |
668 | static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo)); |
669 | |
670 | QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::foo)) == |
671 | static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo)); |
672 | |
673 | // void returning overloaded const member functions |
674 | QVERIFY(QOverload<>::of(&Overloaded::constFoo) == |
675 | static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo)); |
676 | |
677 | QVERIFY(QOverload<QByteArray>::of(&Overloaded::constFoo) == |
678 | static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo)); |
679 | |
680 | QVERIFY((QOverload<QByteArray, const QString &>::of(&Overloaded::constFoo)) == |
681 | static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo)); |
682 | |
683 | // void returning overloaded const AND non-const member functions |
684 | QVERIFY(QNonConstOverload<>::of(&Overloaded::mixedFoo) == |
685 | static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo)); |
686 | |
687 | QVERIFY(QConstOverload<QByteArray>::of(&Overloaded::mixedFoo) == |
688 | static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo)); |
689 | |
690 | #if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 // C++14 |
691 | |
692 | // void returning free overloaded functions |
693 | QVERIFY(qOverload<>(&freeOverloaded) == |
694 | static_cast<void (*)()>(&freeOverloaded)); |
695 | |
696 | QVERIFY(qOverload<QByteArray>(&freeOverloaded) == |
697 | static_cast<void (*)(QByteArray)>(&freeOverloaded)); |
698 | |
699 | QVERIFY((qOverload<QByteArray, const QString &>(&freeOverloaded) == |
700 | static_cast<void (*)(QByteArray, const QString &)>(&freeOverloaded))); |
701 | |
702 | // value returning free overloaded functions |
703 | QVERIFY(qOverload<>(&freeOverloadedGet) == |
704 | static_cast<QByteArray (*)()>(&freeOverloadedGet)); |
705 | |
706 | QVERIFY(qOverload<QByteArray>(&freeOverloadedGet) == |
707 | static_cast<void (*)(QByteArray)>(&freeOverloadedGet)); |
708 | |
709 | // void returning overloaded member functions |
710 | QVERIFY(qOverload<>(&Overloaded::foo) == |
711 | static_cast<void (Overloaded::*)()>(&Overloaded::foo)); |
712 | |
713 | QVERIFY(qOverload<QByteArray>(&Overloaded::foo) == |
714 | static_cast<void (Overloaded::*)(QByteArray)>(&Overloaded::foo)); |
715 | |
716 | QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::foo)) == |
717 | static_cast<void (Overloaded::*)(QByteArray, const QString &)>(&Overloaded::foo)); |
718 | |
719 | // void returning overloaded const member functions |
720 | QVERIFY(qOverload<>(&Overloaded::constFoo) == |
721 | static_cast<void (Overloaded::*)() const>(&Overloaded::constFoo)); |
722 | |
723 | QVERIFY(qOverload<QByteArray>(&Overloaded::constFoo) == |
724 | static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::constFoo)); |
725 | |
726 | QVERIFY((qOverload<QByteArray, const QString &>(&Overloaded::constFoo)) == |
727 | static_cast<void (Overloaded::*)(QByteArray, const QString &) const>(&Overloaded::constFoo)); |
728 | |
729 | // void returning overloaded const AND non-const member functions |
730 | QVERIFY(qNonConstOverload<>(&Overloaded::mixedFoo) == |
731 | static_cast<void (Overloaded::*)()>(&Overloaded::mixedFoo)); |
732 | |
733 | QVERIFY(qConstOverload<QByteArray>(&Overloaded::mixedFoo) == |
734 | static_cast<void (Overloaded::*)(QByteArray) const>(&Overloaded::mixedFoo)); |
735 | #endif |
736 | |
737 | #endif |
738 | } |
739 | |
740 | |
741 | QTEST_APPLESS_MAIN(tst_QGlobal) |
742 | #include "tst_qglobal.moc" |
743 | |