summaryrefslogtreecommitdiffstats
path: root/tests/auto/other/compiler
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-11-23 07:13:00 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2015-11-23 07:13:00 +0100
commit1ed7a67a4cef8350103e4ea33b4bbd084f5d4c2d (patch)
tree03dd7b6f8d9ccc02da6d0d882793ec62c71b00f7 /tests/auto/other/compiler
parentdbb7817e13bc7f7ccb8f04b00a65eb3dcf8d25f8 (diff)
parent6a2b17eeec2d171d2afa17bdbc36456346bfd13b (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.cpp187
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
}