summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-01-03 17:18:02 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-10-03 11:47:17 +0200
commit889d40ebe2d9d0e92caea2749608720f7c088173 (patch)
treea68214fbf5a0dc9b1488e4ae79a499dabc1cc445 /src/corelib/kernel
parent990e2e4fb8ef546b89b5e83e659771edd5b4ed3e (diff)
Centralize the implementation of move assignment operators
At the moment we have two main strategies for dealing with move assignment in Qt: 1) move-and-swap, used by "containers" (in the broad sense): containers, but also smart pointers and similar classes that can hold user-defined types; 2) pure swap, used by containers that hold only memory (e.g. QString, QByteArray, ...) as well as most implicitly shared datatypes. Given the fact that a move assignment operator's code is just boilerplate (whether it's move-and-swap or pure swap), provide two _strictly internal_ macros to help write them, and apply the macros across corelib and gui, porting away from the hand-rolled implementations. The rule of thumb when porting to the new macros is: * Try to stick to the existing code behavior, unless broken * if changing, then follow this checklist: * if the class does not have a move constructor => pure swap (but consider ADDING a move constructor, if possible!) * if the class does have a move constructor, try to follow the criteria above, namely: * if the class holds only memory, pure swap; * if the class may hold anything else but memory (file handles, etc.), then move and swap. Noteworthy details: * some operators planned to be removed in Qt 6 were not ported; * as drive-by, some move constructors were simplified to be using qExchange(); others were outright broken and got fixed; * some contained some more interesting code and were not touched. Change-Id: Idaab3489247dcbabb6df3fa1e5286b69e1d372e9 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qbasictimer.h6
-rw-r--r--src/corelib/kernel/qcore_mac_p.h37
-rw-r--r--src/corelib/kernel/qmetaobject.cpp8
-rw-r--r--src/corelib/kernel/qobjectdefs.h11
-rw-r--r--src/corelib/kernel/qvariant.h3
-rw-r--r--src/corelib/kernel/qwinregistry_p.h6
6 files changed, 31 insertions, 40 deletions
diff --git a/src/corelib/kernel/qbasictimer.h b/src/corelib/kernel/qbasictimer.h
index b9bfd636bc..64a9acbe6e 100644
--- a/src/corelib/kernel/qbasictimer.h
+++ b/src/corelib/kernel/qbasictimer.h
@@ -61,11 +61,7 @@ public:
: id{qExchange(other.id, 0)}
{}
- QBasicTimer& operator=(QBasicTimer &&other) noexcept
- {
- QBasicTimer{std::move(other)}.swap(*this);
- return *this;
- }
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QBasicTimer)
void swap(QBasicTimer &other) noexcept { qSwap(id, other.id); }
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index 2d33e2ca95..ef31b1928c 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -260,21 +260,12 @@ public:
QAppleLogActivity(os_activity_t activity) : activity(activity) {}
~QAppleLogActivity() { if (activity) leave(); }
- QAppleLogActivity(const QAppleLogActivity &) = delete;
- QAppleLogActivity& operator=(const QAppleLogActivity &) = delete;
+ Q_DISABLE_COPY(QAppleLogActivity)
QAppleLogActivity(QAppleLogActivity&& other)
- : activity(other.activity), state(other.state) { other.activity = nullptr; }
+ : activity(qExchange(other.activity, nullptr)), state(other.state) {}
- QAppleLogActivity& operator=(QAppleLogActivity &&other)
- {
- if (this != &other) {
- activity = other.activity;
- state = other.state;
- other.activity = nullptr;
- }
- return *this;
- }
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QAppleLogActivity)
QAppleLogActivity&& enter()
{
@@ -343,18 +334,14 @@ public:
#endif
QMacNotificationObserver(const QMacNotificationObserver& other) = delete;
- QMacNotificationObserver(QMacNotificationObserver&& other) : observer(other.observer) {
- other.observer = nullptr;
- }
+ QMacNotificationObserver(QMacNotificationObserver&& other) : observer(qExchange(other.observer, nullptr)) {}
QMacNotificationObserver &operator=(const QMacNotificationObserver& other) = delete;
- QMacNotificationObserver &operator=(QMacNotificationObserver&& other) {
- if (this != &other) {
- remove();
- observer = other.observer;
- other.observer = nullptr;
- }
- return *this;
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QMacNotificationObserver)
+
+ void swap(QMacNotificationObserver &other) noexcept
+ {
+ qSwap(observer, other.observer);
}
void remove();
@@ -397,11 +384,7 @@ public:
return *this;
}
- QMacKeyValueObserver &operator=(QMacKeyValueObserver &&other) {
- QMacKeyValueObserver tmp(std::move(other));
- swap(tmp, *this);
- return *this;
- }
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QMacKeyValueObserver)
void removeObserver();
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index c537293347..3bb3e33465 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -1598,6 +1598,14 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase *
*/
/*!
+ \fn QMetaObject::Connection::swap(Connection &other)
+ \since 5.15
+
+ Swaps this Connection instance with \a other. This operation is very fast
+ and never fails.
+*/
+
+/*!
\class QMetaMethod
\inmodule QtCore
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 16478d889f..38a87e2dcb 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -459,11 +459,16 @@ public:
operator RestrictedBool() const { return d_ptr && isConnected_helper() ? &Connection::d_ptr : nullptr; }
#endif
- Connection(Connection &&o) noexcept : d_ptr(o.d_ptr) { o.d_ptr = nullptr; }
- Connection &operator=(Connection &&other) noexcept
- { qSwap(d_ptr, other.d_ptr); return *this; }
+ Connection(Connection &&o) noexcept : d_ptr(qExchange(o.d_ptr, nullptr)) {}
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Connection)
+ void swap(Connection &o) noexcept { qSwap(d_ptr, o.d_ptr); }
};
+inline void swap(QMetaObject::Connection &lhs, QMetaObject::Connection &rhs) noexcept
+{
+ lhs.swap(rhs);
+}
+
inline const QMetaObject *QMetaObject::superClass() const
{ return d.superdata; }
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index c28f841356..1bf904618f 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -234,8 +234,7 @@ class Q_CORE_EXPORT QVariant
QVariant& operator=(const QVariant &other);
inline QVariant(QVariant &&other) noexcept : d(other.d)
{ other.d = Private(); }
- inline QVariant &operator=(QVariant &&other) noexcept
- { QVariant moved(std::move(other)); swap(moved); return *this; }
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QVariant)
inline void swap(QVariant &other) noexcept { qSwap(d, other.d); }
diff --git a/src/corelib/kernel/qwinregistry_p.h b/src/corelib/kernel/qwinregistry_p.h
index d249a97988..a456292835 100644
--- a/src/corelib/kernel/qwinregistry_p.h
+++ b/src/corelib/kernel/qwinregistry_p.h
@@ -68,9 +68,9 @@ public:
REGSAM permissions = KEY_READ, REGSAM access = 0);
~QWinRegistryKey();
- QWinRegistryKey(QWinRegistryKey &&other) noexcept { swap(other); }
- QWinRegistryKey &operator=(QWinRegistryKey &&other) noexcept { swap(other); return *this; }
-
+ QWinRegistryKey(QWinRegistryKey &&other) noexcept
+ : m_key(qExchange(other.m_key, nullptr)) {}
+ QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QWinRegistryKey)
void swap(QWinRegistryKey &other) noexcept { qSwap(m_key, other.m_key); }
bool isValid() const { return m_key != nullptr; }