summaryrefslogtreecommitdiffstats
path: root/tests/auto/other
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2015-11-10 12:41:37 +0100
committerMarc Mutz <marc.mutz@kdab.com>2015-11-22 12:26:20 +0000
commit5660ce600422e734aa40086efd58c1ab7815eb3e (patch)
treee6374f1cccd19ac6e18e746f4e9947b38b56e7c0 /tests/auto/other
parentecb6835a9fa0501cefcb1ab7f02e5bb7736afcd4 (diff)
tst_compiler: check more cases for RVALUE_REFS
Check that we can use std::forward, and that the compiler synthesizes move special member functions when it should. MSVC only supports the latter since the Nov 2013 CTP, which, for our intents and purposes, means VC2015. Change-Id: I8d8e4ae064abce90076a05b3b637950ab7d21dac Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'tests/auto/other')
-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
}