Add support for rvalue-references in QArrayDataPointer
authorJoão Abecasis <joao.abecasis@nokia.com>
Fri, 10 Feb 2012 15:13:56 +0000 (16:13 +0100)
committerQt by Nokia <qt-info@nokia.com>
Mon, 13 Feb 2012 09:40:21 +0000 (10:40 +0100)
I love how this magically makes SimpleVector move-aware :-)

Change-Id: I5cb75954d70cf256863c33e684ebc4551ac94f87
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
src/corelib/tools/qarraydatapointer.h
tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp

index 695a6f8..f5ad53a 100644 (file)
@@ -86,6 +86,20 @@ public:
         return *this;
     }
 
+#ifdef Q_COMPILER_RVALUE_REFS
+    QArrayDataPointer(QArrayDataPointer &&other)
+        : d(other.d)
+    {
+        other.d = Data::sharedNull();
+    }
+
+    QArrayDataPointer &operator=(QArrayDataPointer &&other)
+    {
+        this->swap(other);
+        return *this;
+    }
+#endif
+
     DataOps &operator*() const
     {
         Q_ASSERT(d);
index 6a42f4d..00873a8 100644 (file)
@@ -84,6 +84,7 @@ private slots:
     void fromRawData();
     void literals();
     void variadicLiterals();
+    void rValueReferences();
 };
 
 template <class T> const T &const_(const T &t) { return t; }
@@ -1274,5 +1275,50 @@ void tst_QArrayData::variadicLiterals()
 #endif // defined(Q_COMPILER_VARIADIC_MACROS)
 }
 
+#ifdef Q_COMPILER_RVALUE_REFS
+// std::remove_reference is in C++11, but requires library support
+template <class T> struct RemoveReference { typedef T Type; };
+template <class T> struct RemoveReference<T &> { typedef T Type; };
+
+// single-argument std::move is in C++11, but requires library support
+template <class T>
+typename RemoveReference<T>::Type &&cxx11Move(T &&t)
+{
+    return static_cast<typename RemoveReference<T>::Type &&>(t);
+}
+#endif
+
+void tst_QArrayData::rValueReferences()
+{
+#ifdef Q_COMPILER_RVALUE_REFS
+    SimpleVector<int> v1(1, 42);
+    SimpleVector<int> v2;
+
+    const SimpleVector<int>::const_iterator begin = v1.constBegin();
+
+    QVERIFY(!v1.isNull());
+    QVERIFY(v2.isNull());
+
+    // move-assign
+    v2 = cxx11Move(v1);
+
+    QVERIFY(v1.isNull());
+    QVERIFY(!v2.isNull());
+    QCOMPARE(v2.constBegin(), begin);
+
+    SimpleVector<int> v3(cxx11Move(v2));
+
+    QVERIFY(v1.isNull());
+    QVERIFY(v2.isNull());
+    QVERIFY(!v3.isNull());
+    QCOMPARE(v3.constBegin(), begin);
+
+    QCOMPARE(v3.size(), size_t(1));
+    QCOMPARE(v3.front(), 42);
+#else
+    QSKIP("RValue references are not supported in current configuration");
+#endif
+}
+
 QTEST_APPLESS_MAIN(tst_QArrayData)
 #include "tst_qarraydata.moc"