summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-09-28 10:32:00 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2020-09-29 20:32:42 +0200
commit04641454beb27f667062dbf79116729f159b0041 (patch)
tree2664d504dbb17f10792831f6e3b85e31640f3fba /src/corelib/kernel
parent6b4e0c5803b4b8b4396791ba436d9692195993d6 (diff)
Disable moving of QProperty
The semantics are not very intuitive, and it opens a can of worms with regards to what should happen with observers that observe that property. Change-Id: I6fb00b7693904b968224cc87d098bbd0ea776ba3 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qproperty.cpp47
-rw-r--r--src/corelib/kernel/qproperty.h10
-rw-r--r--src/corelib/kernel/qproperty_p.h12
-rw-r--r--src/corelib/kernel/qpropertyprivate.h4
4 files changed, 21 insertions, 52 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp
index 4fdf0d8100..3a2c8dcc0c 100644
--- a/src/corelib/kernel/qproperty.cpp
+++ b/src/corelib/kernel/qproperty.cpp
@@ -196,39 +196,6 @@ QMetaType QUntypedPropertyBinding::valueMetaType() const
return d->valueMetaType();
}
-QPropertyBindingData::QPropertyBindingData(QPropertyBindingData &&other, QUntypedPropertyData *propertyDataPtr)
-{
- std::swap(d_ptr, other.d_ptr);
- QPropertyBindingDataPointer d{this};
- d.setFirstObserver(nullptr);
- if (auto binding = d.bindingPtr())
- binding->setProperty(propertyDataPtr);
-}
-
-void QPropertyBindingData::moveAssign(QPropertyBindingData &&other, QUntypedPropertyData *propertyDataPtr)
-{
- if (&other == this)
- return;
-
- QPropertyBindingDataPointer d{this};
- auto observer = d.firstObserver();
- d.setFirstObserver(nullptr);
-
- if (auto binding = d.bindingPtr()) {
- binding->unlinkAndDeref();
- d_ptr &= FlagMask;
- }
-
- std::swap(d_ptr, other.d_ptr);
-
- if (auto binding = d.bindingPtr())
- binding->setProperty(propertyDataPtr);
-
- d.setFirstObserver(observer.ptr);
-
- // The caller will have to notify observers.
-}
-
QPropertyBindingData::~QPropertyBindingData()
{
QPropertyBindingDataPointer d{this};
@@ -286,6 +253,12 @@ QUntypedPropertyBinding QPropertyBindingData::setBinding(const QUntypedPropertyB
return QUntypedPropertyBinding(oldBinding.data());
}
+QPropertyBindingData::QPropertyBindingData(QPropertyBindingData &&other) : d_ptr(std::exchange(other.d_ptr, 0))
+{
+ QPropertyBindingDataPointer d{this};
+ d.fixupFirstObserverAfterMove();
+}
+
QPropertyBindingPrivate *QPropertyBindingData::binding() const
{
QPropertyBindingDataPointer d{this};
@@ -694,12 +667,6 @@ QString QPropertyBindingError::description() const
*/
/*!
- \fn template <typename T> QProperty<T> &QProperty<T>::operator=(QProperty &&other)
-
- Move-assigns \a other to this QProperty instance.
-*/
-
-/*!
\fn template <typename T> QProperty<T>::QProperty(const QPropertyBinding<T> &binding)
Constructs a property that is tied to the provided \a binding expression. The
@@ -1395,7 +1362,7 @@ struct QBindingStoragePrivate
if (index == newData->size)
index = 0;
}
- new (pp + index) Pair{p->data, QPropertyBindingData(std::move(p->bindingData), p->data)};
+ new (pp + index) Pair{p->data, QPropertyBindingData(std::move(p->bindingData))};
}
}
// data has been moved, no need to call destructors on old Pairs
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h
index 09b2642e73..156696dace 100644
--- a/src/corelib/kernel/qproperty.h
+++ b/src/corelib/kernel/qproperty.h
@@ -315,7 +315,6 @@ public:
QProperty() = default;
explicit QProperty(parameter_type initialValue) : QPropertyData<T>(initialValue) {}
explicit QProperty(rvalue_ref initialValue) : QPropertyData<T>(std::move(initialValue)) {}
- QProperty(QProperty &&other) : QPropertyData<T>(std::move(other.val)), d(std::move(other.d), this) { notify(); }
explicit QProperty(const QPropertyBinding<T> &binding)
: QProperty()
{ setBinding(binding); }
@@ -329,13 +328,6 @@ public:
template <typename Functor>
explicit QProperty(Functor &&f);
#endif
- QProperty &operator=(QProperty &&other)
- {
- this->val = std::move(other.val);
- d.moveAssign(std::move(other.d), this);
- notify();
- return *this;
- }
~QProperty() = default;
parameter_type value() const
@@ -460,7 +452,7 @@ private:
d.notifyObservers(this);
}
- Q_DISABLE_COPY(QProperty)
+ Q_DISABLE_COPY_MOVE(QProperty)
};
namespace Qt {
diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h
index 614756a670..1bf308e8ea 100644
--- a/src/corelib/kernel/qproperty_p.h
+++ b/src/corelib/kernel/qproperty_p.h
@@ -81,6 +81,7 @@ struct Q_AUTOTEST_EXPORT QPropertyBindingDataPointer
observer->prev = reinterpret_cast<QPropertyObserver**>(&(ptr->d_ptr));
ptr->d_ptr = (reinterpret_cast<quintptr>(observer) & ~QtPrivate::QPropertyBindingData::FlagMask);
}
+ void fixupFirstObserverAfterMove() const;
void addObserver(QPropertyObserver *observer);
void setFirstObserver(QPropertyObserver *observer);
QPropertyObserverPointer firstObserver() const;
@@ -293,6 +294,17 @@ inline void QPropertyBindingDataPointer::setFirstObserver(QPropertyObserver *obs
ptr->d_ptr = reinterpret_cast<quintptr>(observer) | (ptr->d_ptr & QtPrivate::QPropertyBindingData::FlagMask);
}
+inline void QPropertyBindingDataPointer::fixupFirstObserverAfterMove() const
+{
+ // If QPropertyBindingData has been moved, and it has an observer
+ // we have to adjust the firstObesrver's prev pointer to point to
+ // the moved to QPropertyBindingData's d_ptr
+ if (ptr->d_ptr & QtPrivate::QPropertyBindingData::BindingBit)
+ return; // nothing to do if the observer is stored in the binding
+ if (auto observer = firstObserver())
+ observer.ptr->prev = reinterpret_cast<QPropertyObserver**>(&(ptr->d_ptr));
+}
+
inline QPropertyObserverPointer QPropertyBindingDataPointer::firstObserver() const
{
if (auto *binding = bindingPtr())
diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h
index dd344c209a..26877e0315 100644
--- a/src/corelib/kernel/qpropertyprivate.h
+++ b/src/corelib/kernel/qpropertyprivate.h
@@ -88,12 +88,10 @@ class Q_CORE_EXPORT QPropertyBindingData
Q_DISABLE_COPY(QPropertyBindingData)
public:
QPropertyBindingData() = default;
- QPropertyBindingData(QPropertyBindingData &&other, QUntypedPropertyData *propertyDataPtr);
+ QPropertyBindingData(QPropertyBindingData &&other);
QPropertyBindingData &operator=(QPropertyBindingData &&other) = delete;
~QPropertyBindingData();
- void moveAssign(QPropertyBindingData &&other, QUntypedPropertyData *propertyDataPtr);
-
bool hasBinding() const { return d_ptr & BindingBit; }
QUntypedPropertyBinding setBinding(const QUntypedPropertyBinding &newBinding,