summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qproperty.h6
-rw-r--r--src/corelib/kernel/qpropertyprivate.h12
-rw-r--r--tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp72
3 files changed, 84 insertions, 6 deletions
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h
index 5d26c1c0f4..c2949c3022 100644
--- a/src/corelib/kernel/qproperty.h
+++ b/src/corelib/kernel/qproperty.h
@@ -155,8 +155,10 @@ class QPropertyBinding : public QUntypedPropertyBinding
{
PropertyType *propertyPtr = static_cast<PropertyType *>(dataPtr);
PropertyType newValue = impl();
- if (newValue == *propertyPtr)
- return false;
+ if constexpr (QTypeTraits::has_operator_equal_v<PropertyType>) {
+ if (newValue == *propertyPtr)
+ return false;
+ }
*propertyPtr = std::move(newValue);
return true;
}
diff --git a/src/corelib/kernel/qpropertyprivate.h b/src/corelib/kernel/qpropertyprivate.h
index ad5ed59e88..dde6bb8d01 100644
--- a/src/corelib/kernel/qpropertyprivate.h
+++ b/src/corelib/kernel/qpropertyprivate.h
@@ -139,15 +139,19 @@ public:
T getValue() const { return value; }
bool setValueAndReturnTrueIfChanged(T &&v)
{
- if (v == value)
- return false;
+ if constexpr (QTypeTraits::has_operator_equal_v<T>) {
+ if (v == value)
+ return false;
+ }
value = std::move(v);
return true;
}
bool setValueAndReturnTrueIfChanged(const T &v)
{
- if (v == value)
- return false;
+ if constexpr (QTypeTraits::has_operator_equal_v<T>) {
+ if (v == value)
+ return false;
+ }
value = v;
return true;
}
diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
index 5f17bcb2b7..41cf60b55f 100644
--- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
+++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp
@@ -72,6 +72,7 @@ private slots:
void notifiedProperty();
void notifiedPropertyWithOldValueCallback();
void notifiedPropertyWithGuard();
+ void typeNoOperatorEqual();
};
void tst_QProperty::functorBinding()
@@ -985,6 +986,77 @@ void tst_QProperty::notifiedPropertyWithGuard()
}
}
+void tst_QProperty::typeNoOperatorEqual()
+{
+ struct Uncomparable
+ {
+ int data = -1;
+ bool changedCalled = false;
+
+ Uncomparable(int value = 0)
+ : data(value)
+ {}
+ Uncomparable(const Uncomparable &other)
+ {
+ data = other.data;
+ changedCalled = false;
+ }
+ Uncomparable(Uncomparable &&other)
+ {
+ data = other.data;
+ changedCalled = false;
+ other.data = -1;
+ other.changedCalled = false;
+ }
+ Uncomparable &operator=(const Uncomparable &other)
+ {
+ data = other.data;
+ return *this;
+ }
+ Uncomparable &operator=(Uncomparable &&other)
+ {
+ data = other.data;
+ changedCalled = false;
+ other.data = -1;
+ other.changedCalled = false;
+ return *this;
+ }
+ bool operator==(const Uncomparable&) = delete;
+ bool operator!=(const Uncomparable&) = delete;
+
+ void changed()
+ {
+ changedCalled = true;
+ }
+ };
+
+ Uncomparable u1 = { 13 };
+ Uncomparable u2 = { 27 };
+
+ QProperty<Uncomparable> p1;
+ QProperty<Uncomparable> p2 = Qt::makePropertyBinding(p1);
+
+ QCOMPARE(p1.value().data, p2.value().data);
+ p1.setValue(u1);
+ QCOMPARE(p1.value().data, u1.data);
+ QCOMPARE(p1.value().data, p2.value().data);
+ p2.setValue(u2);
+ QCOMPARE(p1.value().data, u1.data);
+ QCOMPARE(p2.value().data, u2.data);
+
+ QProperty<Uncomparable> p3 = Qt::makePropertyBinding(p1);
+ p1.setValue(u1);
+ QCOMPARE(p1.value().data, p3.value().data);
+
+ QNotifiedProperty<Uncomparable, &Uncomparable::changed> np;
+ QVERIFY(np.value().data != u1.data);
+ np.setValue(&u1, u1);
+ QVERIFY(u1.changedCalled);
+ u1.changedCalled = false;
+ QCOMPARE(np.value().data, u1.data);
+ np.setValue(&u1, u1);
+ QVERIFY(u1.changedCalled);
+}
QTEST_MAIN(tst_QProperty);