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
37class tst_QGlobal: public QObject
38{
39 Q_OBJECT
40
41private 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
60extern "C" { // functions in qglobal.c
61void tst_GlobalTypes();
62int tst_QtVersion();
63const char *tst_qVersion();
64}
65
66void 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
76void 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
97void 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
171void 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
204void 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
268void 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.
280class MyTrue
281{
282public:
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
303struct 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 }
312private:
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
319struct TypeDef
320{
321 typedef int T;
322 Q_STATIC_ASSERT(sizeof(T));
323 Q_STATIC_ASSERT_X(sizeof(T), "");
324};
325
326template<typename T1, typename T2>
327struct 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
341struct 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
350void 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
367static int qConstructorFunctionValue;
368static void qConstructorFunctionCtor()
369{
370 qConstructorFunctionValue = 123;
371}
372Q_CONSTRUCTOR_FUNCTION(qConstructorFunctionCtor);
373
374void tst_QGlobal::qConstructorFunction()
375{
376 QCOMPARE(qConstructorFunctionValue, 123);
377}
378
379static int qStartupFunctionValue;
380static void myStartupFunc()
381{
382 Q_ASSERT(QCoreApplication::instance());
383 if (QCoreApplication::instance())
384 qStartupFunctionValue += 124;
385}
386
387Q_COREAPP_STARTUP_FUNCTION(myStartupFunc)
388
389void 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
398void tst_QGlobal::qCoreAppStartupFunctionRestart()
399{
400 qStartupFunctionValue = 0;
401 qCoreAppStartupFunction();
402 qStartupFunctionValue = 0;
403 qCoreAppStartupFunction();
404}
405
406struct isEnum_A {
407 int n_;
408};
409
410enum isEnum_B_Byte { isEnum_B_Byte_x = 63 };
411enum isEnum_B_Short { isEnum_B_Short_x = 1024 };
412enum isEnum_B_Int { isEnum_B_Int_x = 1 << 20 };
413
414union isEnum_C {};
415
416class isEnum_D {
417public:
418 operator int() const;
419};
420
421class isEnum_E {
422private:
423 operator int() const;
424};
425
426class isEnum_F {
427public:
428 enum AnEnum {};
429};
430
431struct Empty {};
432template <class T> struct AlignmentInStruct { T dummy; };
433
434typedef int (*fun) ();
435typedef 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
471void 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
537void 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
551typedef QPair<const char *, const char *> stringpair;
552Q_DECLARE_METATYPE(stringpair)
553
554void 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
591void 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
610void 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
620struct 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
634void freeOverloaded() {}
635void freeOverloaded(QByteArray) {}
636void freeOverloaded(QByteArray, const QString &) {}
637
638void freeOverloadedGet(QByteArray) {}
639QByteArray freeOverloadedGet() { return QByteArray(); }
640
641
642void 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
741QTEST_APPLESS_MAIN(tst_QGlobal)
742#include "tst_qglobal.moc"
743

source code of qtbase/tests/auto/corelib/global/qglobal/tst_qglobal.cpp