diff --git a/src/corelib/tools/quniquehandle_p.h b/src/corelib/tools/quniquehandle_p.h index d388b1bb0fc..815d0768b06 100644 --- a/src/corelib/tools/quniquehandle_p.h +++ b/src/corelib/tools/quniquehandle_p.h @@ -17,6 +17,8 @@ #include #include +#include +#include #include #include @@ -125,14 +127,13 @@ public: close(); } - QUniqueHandle& operator=(QUniqueHandle &&rhs) noexcept + void swap(QUniqueHandle &other) noexcept { - if (this != std::addressof(rhs)) - reset(rhs.release()); - - return *this; + qSwap(m_handle, other.m_handle); } + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QUniqueHandle) + QUniqueHandle(const QUniqueHandle &) = delete; QUniqueHandle &operator=(const QUniqueHandle &) = delete; @@ -219,6 +220,13 @@ private: // clang-format on +template +void swap(QUniqueHandle &lhs, QUniqueHandle &rhs) noexcept +{ + lhs.swap(rhs); +} + + QT_END_NAMESPACE #endif diff --git a/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp index ffcaddb1112..448ea0964fb 100644 --- a/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp +++ b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp @@ -259,16 +259,51 @@ private slots: void swap_swapsOwnership() const { - const auto resource0 = GlobalResource::open(); - const auto resource1 = GlobalResource::open(); + { // Swapping valid and invalid handle + Handle h0{ GlobalResource::open() }; + Handle h1; - Handle h0{ resource0 }; - Handle h1{ resource1 }; + h0.swap(h1); - std::swap(h0, h1); + QVERIFY(!h0.isValid()); + QVERIFY(h1.isValid()); + } + { // Swapping valid handles + const auto resource0 = GlobalResource::open(); + const auto resource1 = GlobalResource::open(); - QCOMPARE_EQ(h0.get(), resource1); - QCOMPARE_EQ(h1.get(), resource0); + Handle h0{ resource0 }; + Handle h1{ resource1 }; + + h0.swap(h1); + + QCOMPARE_EQ(h0.get(), resource1); + QCOMPARE_EQ(h1.get(), resource0); + } + { // std::swap + const auto resource0 = GlobalResource::open(); + const auto resource1 = GlobalResource::open(); + + Handle h0{ resource0 }; + Handle h1{ resource1 }; + + std::swap(h0, h1); + + QCOMPARE_EQ(h0.get(), resource1); + QCOMPARE_EQ(h1.get(), resource0); + } + { // swap + const auto resource0 = GlobalResource::open(); + const auto resource1 = GlobalResource::open(); + + Handle h0{ resource0 }; + Handle h1{ resource1 }; + + swap(h0, h1); + + QCOMPARE_EQ(h0.get(), resource1); + QCOMPARE_EQ(h1.get(), resource0); + } } void comparison_behavesAsInt_whenHandleTypeIsInt_data() const