Don't test for equality if types can't be compared
For types that don't have an operator==(), always trigger the binding and the changed notification. Task-number: QTBUG-85578 Change-Id: I41374f6d13c88106f4de83864e82172f3a248150 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
5f3f23462e
commit
124590850b
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user