summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qproperty.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h
index 4a144911771..f4e7942e947 100644
--- a/src/corelib/kernel/qproperty.h
+++ b/src/corelib/kernel/qproperty.h
@@ -360,6 +360,17 @@ class QProperty : public QPropertyData<T>
return false;
}
+ template <typename U, typename = void>
+ struct has_operator_equal_to : std::false_type{};
+
+ template <typename U>
+ struct has_operator_equal_to<U, std::void_t<decltype(bool(std::declval<const T&>() == std::declval<const U&>()))>>
+ : std::true_type{};
+
+ template <typename U>
+ static constexpr bool has_operator_equal_to_v =
+ !std::is_same_v<U, T> && has_operator_equal_to<U>::value;
+
public:
using value_type = typename QPropertyData<T>::value_type;
using parameter_type = typename QPropertyData<T>::parameter_type;
@@ -388,6 +399,23 @@ public:
QT_DECLARE_EQUALITY_OPERATORS_HELPER(QProperty, T, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(QProperty, T, /* non-constexpr */, noexcept(false), template <typename Ty = T, std::enable_if_t<QTypeTraits::has_operator_equal_v<Ty>>* = nullptr>)
+ QT_DECLARE_EQUALITY_OPERATORS_HELPER(QProperty, U, /* non-constexpr */, noexcept(false), template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>)
+ QT_DECLARE_EQUALITY_OPERATORS_REVERSED_HELPER(QProperty, U, /* non-constexpr */, noexcept(false), template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>)
+
+ // Explicitly delete op==(QProperty<T>, QProperty<U>) for different T & U.
+ // We do not want implicit conversions here!
+ // However, GCC complains about using a default template argument in a
+ // friend declaration, while Clang and MSVC are fine. So, skip GCC here.
+#if !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
+#define QPROPERTY_DECL_DELETED_EQ_OP \
+ Q_DECL_EQ_DELETE_X("Call .value() on one of the properties explicitly.")
+ template <typename U, std::enable_if_t<!std::is_same_v<T, U>>* = nullptr>
+ friend void operator==(const QProperty &, const QProperty<U> &) QPROPERTY_DECL_DELETED_EQ_OP;
+ template <typename U, std::enable_if_t<!std::is_same_v<T, U>>* = nullptr>
+ friend void operator!=(const QProperty &, const QProperty<U> &) QPROPERTY_DECL_DELETED_EQ_OP;
+#undef QPROPERTY_DECL_DELETED_EQ_OP
+#endif // !defined(Q_CC_GNU) || defined(Q_CC_CLANG)
+
parameter_type value() const
{
d.registerWithCurrentlyEvaluatingBinding();
@@ -520,6 +548,12 @@ private:
return lhs.value() == rhs;
}
+ template <typename U, std::enable_if_t<has_operator_equal_to_v<U>>* = nullptr>
+ friend bool comparesEqual(const QProperty &lhs, const U &rhs)
+ {
+ return lhs.value() == rhs;
+ }
+
void notify()
{
d.notifyObservers(this);