Implement QUniqueHandle move assignment using MOVE_AND_SWAP macro

This removes boilerplate and the extra complication of std::addressof.

Task-number: QTBUG-132507
Pick-to: 6.8
Change-Id: I07091ec0ac526975cf55361a9811fad77eb152c2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 30ae70a110ee2460744e4fb78bae29b75effbf72)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Jøger Hansegård 2025-01-03 21:56:47 +01:00 committed by Qt Cherry-pick Bot
parent a892eb50d3
commit 11abd87046
2 changed files with 55 additions and 12 deletions

View File

@ -17,6 +17,8 @@
#include <QtCore/qtconfigmacros.h>
#include <QtCore/qassert.h>
#include <QtCore/qswap.h>
#include <QtCore/qtclasshelpermacros.h>
#include <memory>
#include <utility>
@ -139,14 +141,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;
@ -233,6 +234,13 @@ private:
// clang-format on
template <typename Trait>
void swap(QUniqueHandle<Trait> &lhs, QUniqueHandle<Trait> &rhs) noexcept
{
lhs.swap(rhs);
}
QT_END_NAMESPACE
#endif

View File

@ -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