summaryrefslogtreecommitdiffstats
path: root/tests/auto/other/compiler/tst_compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/other/compiler/tst_compiler.cpp')
-rw-r--r--tests/auto/other/compiler/tst_compiler.cpp86
1 files changed, 75 insertions, 11 deletions
diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp
index 981206cc9e..af0fa4682d 100644
--- a/tests/auto/other/compiler/tst_compiler.cpp
+++ b/tests/auto/other/compiler/tst_compiler.cpp
@@ -1128,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
}