diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2015-11-23 07:13:00 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2015-11-23 07:13:00 +0100 |
commit | 1ed7a67a4cef8350103e4ea33b4bbd084f5d4c2d (patch) | |
tree | 03dd7b6f8d9ccc02da6d0d882793ec62c71b00f7 /tests/auto/other/compiler | |
parent | dbb7817e13bc7f7ccb8f04b00a65eb3dcf8d25f8 (diff) | |
parent | 6a2b17eeec2d171d2afa17bdbc36456346bfd13b (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts:
src/corelib/kernel/qcoreapplication.cpp
src/corelib/thread/qthread_unix.cpp
Change-Id: Ia08d613c3f0bd08cb6dc3e3a57257207dfd4a099
Diffstat (limited to 'tests/auto/other/compiler')
-rw-r--r-- | tests/auto/other/compiler/tst_compiler.cpp | 187 |
1 files changed, 173 insertions, 14 deletions
diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index 2c95002cb2..af0fa4682d 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -979,6 +979,20 @@ void tst_Compiler::cxx11_nullptr() #endif } +namespace SomeNamespace { +class AdlOnly { + QVector<int> v; +public: + AdlOnly() : v(5) { std::fill_n(v.begin(), v.size(), 42); } + +private: + friend QVector<int>::const_iterator begin(const AdlOnly &x) { return x.v.begin(); } + friend QVector<int>::const_iterator end(const AdlOnly &x) { return x.v.end(); } + friend QVector<int>::iterator begin(AdlOnly &x) { return x.v.begin(); } + friend QVector<int>::iterator end(AdlOnly &x) { return x.v.end(); } +}; +} + void tst_Compiler::cxx11_range_for() { #ifndef Q_COMPILER_RANGE_FOR @@ -998,6 +1012,85 @@ void tst_Compiler::cxx11_range_for() l << 2; for (int i : ll) QCOMPARE(i, 2); + + { + const int array[] = { 0, 1, 2, 3, 4 }; + int i = 0; + for (const int &e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (int e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (const int e : array) + QCOMPARE(e, array[i++]); +#ifdef Q_COMPILER_AUTO_TYPE + i = 0; + for (const auto &e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (auto &e : array) // auto deducing const + QCOMPARE(e, array[i++]); + i = 0; + for (auto e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (const auto e : array) + QCOMPARE(e, array[i++]); +#endif + } + + { + int array[] = { 0, 1, 2, 3, 4 }; + const int array2[] = { 10, 11, 12, 13, 14 }; + int i = 0; + for (const int &e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (int &e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (int e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (const int e : array) + QCOMPARE(e, array[i++]); +#ifdef Q_COMPILER_AUTO_TYPE + i = 0; + for (const auto &e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (auto &e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (auto e : array) + QCOMPARE(e, array[i++]); + i = 0; + for (const auto e : array) + QCOMPARE(e, array[i++]); +#endif + for (int &e : array) + e += 10; + i = 0; + for (const int &e : array) + QCOMPARE(e, array2[i++]); + } + + { + const SomeNamespace::AdlOnly x; + for (const int &e : x) + QCOMPARE(e, 42); + } + + { + SomeNamespace::AdlOnly x; + for (const int &e : x) + QCOMPARE(e, 42); + for (int &e : x) + e += 10; + for (const int &e : x) + QCOMPARE(e, 52); + } #endif } @@ -1035,24 +1128,88 @@ void tst_Compiler::cxx11_ref_qualifiers() #endif } +class MoveDefinedQString { + QString s; +public: + MoveDefinedQString() : s() {} + explicit MoveDefinedQString(const QString &s) : s(s) {} + MoveDefinedQString(const MoveDefinedQString &other) : s(other.s) {} +#ifdef Q_COMPILER_RVALUE_REFS + MoveDefinedQString(MoveDefinedQString &&other) : s(std::move(other.s)) { other.s.clear(); } + MoveDefinedQString &operator=(MoveDefinedQString &&other) + { s = std::move(other.s); other.s.clear(); return *this; } +#endif + MoveDefinedQString &operator=(const MoveDefinedQString &other) { s = other.s; return *this; } + +private: + friend bool operator==(const MoveDefinedQString &lhs, const MoveDefinedQString &rhs) + { return lhs.s == rhs.s; } + friend bool operator!=(const MoveDefinedQString &lhs, const MoveDefinedQString &rhs) + { return !operator==(lhs, rhs); } + friend char* toString(const MoveDefinedQString &mds) + { using namespace QTest; return toString(mds.s); } +}; + void tst_Compiler::cxx11_rvalue_refs() { #ifndef Q_COMPILER_RVALUE_REFS QSKIP("Compiler does not support C++11 feature"); #else - int i = 1; - i = std::move(i); - - QString s = "Hello"; - QString t = std::move(s); - QCOMPARE(t, QString("Hello")); + // we require std::move: + { + int i = 1; + i = std::move(i); + + MoveDefinedQString s("Hello"); + MoveDefinedQString t = std::move(s); + QCOMPARE(t, MoveDefinedQString("Hello")); + QCOMPARE(s, MoveDefinedQString()); + + s = t; + t = std::move(s); + QCOMPARE(t, MoveDefinedQString("Hello")); + QCOMPARE(s, MoveDefinedQString()); + + MoveDefinedQString &&r = std::move(t); // no actual move! + QCOMPARE(r, MoveDefinedQString("Hello")); + QCOMPARE(t, MoveDefinedQString("Hello")); // so 't' is unchanged + } - s = t; - t = std::move(s); - QCOMPARE(t, QString("Hello")); + // we require std::forward: + { + MoveDefinedQString s("Hello"); + MoveDefinedQString s2 = std::forward<MoveDefinedQString>(s); // forward as rvalue + QCOMPARE(s2, MoveDefinedQString("Hello")); + QCOMPARE(s, MoveDefinedQString()); + + MoveDefinedQString s3 = std::forward<MoveDefinedQString&>(s2); // forward as lvalue + QCOMPARE(s2, MoveDefinedQString("Hello")); + QCOMPARE(s3, MoveDefinedQString("Hello")); + } - QString &&r = std::move(s); - QCOMPARE(r, QString("Hello")); + // supported by MSVC only from November 2013 CTP, but only check for VC2015: +# if !defined(Q_CC_MSVC) || defined(Q_CC_INTEL) || _MSC_VER >= 1900 // VS14 == VC2015 + // we require automatic generation of move special member functions: + { + struct M { MoveDefinedQString s1, s2; }; + M m1 = { MoveDefinedQString("Hello"), MoveDefinedQString("World") }; + QCOMPARE(m1.s1, MoveDefinedQString("Hello")); + QCOMPARE(m1.s2, MoveDefinedQString("World")); + M m2 = std::move(m1); + QCOMPARE(m1.s1, MoveDefinedQString()); + QCOMPARE(m1.s2, MoveDefinedQString()); + QCOMPARE(m2.s1, MoveDefinedQString("Hello")); + QCOMPARE(m2.s2, MoveDefinedQString("World")); + M m3; + QCOMPARE(m3.s1, MoveDefinedQString()); + QCOMPARE(m3.s2, MoveDefinedQString()); + m3 = std::move(m2); + QCOMPARE(m2.s1, MoveDefinedQString()); + QCOMPARE(m2.s2, MoveDefinedQString()); + QCOMPARE(m3.s1, MoveDefinedQString("Hello")); + QCOMPARE(m3.s2, MoveDefinedQString("World")); + } +# endif // MSVC < 2015 #endif } @@ -1265,9 +1422,11 @@ void tst_Compiler::cxx14_decltype_auto() } #if __cpp_return_type_deduction >= 201304 -auto returnTypeDeduction() +auto returnTypeDeduction(bool choice) { - return 1U; + if (choice) + return 1U; + return returnTypeDeduction(!choice); } #endif @@ -1276,7 +1435,7 @@ void tst_Compiler::cxx14_return_type_deduction() #if __cpp_return_type_deduction-0 < 201304 QSKIP("Compiler does not support this C++14 feature"); #else - QCOMPARE(returnTypeDeduction(), 1U); + QCOMPARE(returnTypeDeduction(false), 1U); #endif } |