QWeakPointer: enable move semantics

Also add some tests for QSharedPointer move semantics, too.

Change-Id: I1bdd1fe140acafabe5bc6bff8af49a053ec1f4d5
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2014-02-23 00:01:19 +01:00
parent abf51f0b27
commit c644fab0ed
2 changed files with 71 additions and 0 deletions

View File

@ -617,6 +617,16 @@ public:
QWeakPointer(const QWeakPointer &other) Q_DECL_NOTHROW : d(other.d), value(other.value) QWeakPointer(const QWeakPointer &other) Q_DECL_NOTHROW : d(other.d), value(other.value)
{ if (d) d->weakref.ref(); } { 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 &operator=(const QWeakPointer &other) Q_DECL_NOTHROW
{ {
QWeakPointer copy(other); QWeakPointer copy(other);

View File

@ -63,6 +63,7 @@ private slots:
void basics(); void basics();
void operators(); void operators();
void swap(); void swap();
void moveSemantics();
void useOfForwardDeclared(); void useOfForwardDeclared();
void memoryManagement(); void memoryManagement();
void dropLastReferenceOfForwardDeclared(); void dropLastReferenceOfForwardDeclared();
@ -411,6 +412,66 @@ void tst_QSharedPointer::swap()
QVERIFY(w2.isNull()); QVERIFY(w2.isNull());
} }
void tst_QSharedPointer::moveSemantics()
{
#ifdef Q_COMPILER_RVALUE_REFS
QSharedPointer<int> 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<int> p3 = std::move(p1);
QVERIFY(p1 != control);
QVERIFY(p1.isNull());
QVERIFY(p3 == control);
QVERIFY(!p3.isNull());
QVERIFY(*p3 == 42);
QWeakPointer<int> 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<int> 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() void tst_QSharedPointer::useOfForwardDeclared()
{ {
// this just a compile test: use the forward-declared class // this just a compile test: use the forward-declared class