From c644fab0ed92d79d9ce4e2e756ab1c5634e8d3df Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 23 Feb 2014 00:01:19 +0100 Subject: [PATCH] QWeakPointer: enable move semantics Also add some tests for QSharedPointer move semantics, too. Change-Id: I1bdd1fe140acafabe5bc6bff8af49a053ec1f4d5 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Thiago Macieira --- src/corelib/tools/qsharedpointer_impl.h | 10 +++ .../qsharedpointer/tst_qsharedpointer.cpp | 61 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index c23193c51ac..ace6c5d0939 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -617,6 +617,16 @@ public: QWeakPointer(const QWeakPointer &other) Q_DECL_NOTHROW : d(other.d), value(other.value) { if (d) d->weakref.ref(); } +#ifdef Q_COMPILER_RVALUE_REFS + QWeakPointer(QWeakPointer &&other) Q_DECL_NOTHROW + : d(other.d), value(other.value) + { + other.d = Q_NULLPTR; + other.value = Q_NULLPTR; + } + QWeakPointer &operator=(QWeakPointer &&other) Q_DECL_NOTHROW + { QWeakPointer moved(std::move(other)); swap(moved); return *this; } +#endif QWeakPointer &operator=(const QWeakPointer &other) Q_DECL_NOTHROW { QWeakPointer copy(other); diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 77418032245..d88a70c1e57 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -63,6 +63,7 @@ private slots: void basics(); void operators(); void swap(); + void moveSemantics(); void useOfForwardDeclared(); void memoryManagement(); void dropLastReferenceOfForwardDeclared(); @@ -411,6 +412,66 @@ void tst_QSharedPointer::swap() QVERIFY(w2.isNull()); } +void tst_QSharedPointer::moveSemantics() +{ +#ifdef Q_COMPILER_RVALUE_REFS + QSharedPointer p1, p2(new int(42)), control = p2; + QVERIFY(p1 != control); + QVERIFY(p1.isNull()); + QVERIFY(p2 == control); + QVERIFY(!p2.isNull()); + QVERIFY(*p2 == 42); + + // move assignment + p1 = std::move(p2); + QVERIFY(p1 == control); + QVERIFY(!p1.isNull()); + QVERIFY(p2 != control); + QVERIFY(p2.isNull()); + QVERIFY(*p1 == 42); + + // move construction + QSharedPointer p3 = std::move(p1); + QVERIFY(p1 != control); + QVERIFY(p1.isNull()); + QVERIFY(p3 == control); + QVERIFY(!p3.isNull()); + QVERIFY(*p3 == 42); + + QWeakPointer w1, w2 = control; + + QVERIFY(w1.isNull()); + QVERIFY(!w2.isNull()); + QVERIFY(w2.lock() == control); + QVERIFY(!w1.lock()); + + // move assignment + w1 = std::move(w2); + QVERIFY(w2.isNull()); + QVERIFY(!w1.isNull()); + QVERIFY(w1.lock() == control); + QVERIFY(!w2.lock()); + + // move construction + QWeakPointer w3 = std::move(w1); + QVERIFY(w1.isNull()); + QVERIFY(!w3.isNull()); + QVERIFY(w3.lock() == control); + QVERIFY(!w1.lock()); + + p1.reset(); + p2.reset(); + p3.reset(); + control.reset(); + + QVERIFY(w1.isNull()); + QVERIFY(w2.isNull()); + QVERIFY(w3.isNull()); +#else + QSKIP("This test requires C++11 rvalue/move semantics support in the compiler."); +#endif +} + void tst_QSharedPointer::useOfForwardDeclared() { // this just a compile test: use the forward-declared class