43 #include <QtCore/qglobal.h>
44 #include <QtCore/qshareddata.h>
45 #include <QtCore/qstring.h>
46 #include <QtCore/qbindingstorage.h>
48 #include <type_traits>
50 #include <QtCore/qpropertyprivate.h>
52 #if __has_include(<source_location>) && __cplusplus >= 202002L && !defined(Q_CLANG_QDOC)
53 #include <source_location>
54 #if defined(__cpp_lib_source_location)
55 #define QT_SOURCE_LOCATION_NAMESPACE std
56 #define QT_PROPERTY_COLLECT_BINDING_LOCATION
57 #define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation(std::source_location::current())
61 #if __has_include(<experimental/source_location>) && !defined(Q_CLANG_QDOC)
62 #include <experimental/source_location>
63 #if !defined(QT_PROPERTY_COLLECT_BINDING_LOCATION)
64 #if defined(__cpp_lib_experimental_source_location)
65 #define QT_SOURCE_LOCATION_NAMESPACE std::experimental
66 #define QT_PROPERTY_COLLECT_BINDING_LOCATION
67 #define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation(std::experimental::source_location::current())
72 #if !defined(QT_PROPERTY_COLLECT_BINDING_LOCATION)
73 #define QT_PROPERTY_DEFAULT_BINDING_LOCATION QPropertyBindingSourceLocation()
89 class DisableRValueRefs {};
91 static constexpr
bool UseReferences = !(std::is_arithmetic_v<T> || std::is_enum_v<T> || std::is_pointer_v<T>);
95 using rvalue_ref =
typename std::conditional_t<UseReferences, T &&, DisableRValueRefs>;
97 std::conditional_t<QTypeTraits::is_dereferenceable_v<T>,
const T &,
void>>;
113 const char *functionName =
nullptr;
117 #ifdef __cpp_lib_source_location
121 functionName = cppLocation.function_name();
122 line = cppLocation.line();
123 column = cppLocation.column();
126 #ifdef __cpp_lib_experimental_source_location
130 functionName = cppLocation.function_name();
131 line = cppLocation.line();
132 column = cppLocation.column();
176 template<
typename Functor>
201 template <
typename PropertyType>
208 template<
typename Functor>
221 template <
typename Functor>
223 std::enable_if_t<std::is_invocable_v<Functor>> * =
nullptr)
229 struct QPropertyObserverPrivate;
274 template<
typename Property,
typename =
typename Property::InheritsQUntypedPropertyData>
276 { setSource(
property.bindingData()); }
295 template <
typename Functor>
309 template<
typename Property,
typename =
typename Property::InheritsQUntypedPropertyData>
326 template<
typename Functor>
336 template<
typename Functor,
typename Property,
typename =
typename Property::InheritsQUntypedPropertyData>
348 template <
typename T>
352 bool is_equal(
const T &
v)
354 if constexpr (QTypeTraits::has_operator_equal_v<T>) {
374 template <
typename Functor>
376 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * =
nullptr)
380 template <
typename Functor>
387 d.registerWithCurrentlyEvaluatingBinding();
393 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
395 }
else if constexpr (std::is_pointer_v<T>) {
416 if (is_equal(newValue))
418 this->
val = std::move(newValue);
425 if (is_equal(newValue))
427 this->
val = newValue;
457 template <
typename Functor>
460 std::enable_if_t<std::is_invocable_v<Functor>> * =
nullptr)
465 template <
typename Functor>
481 template<
typename Functor>
484 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
488 template<
typename Functor>
491 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
496 template<
typename Functor>
499 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
507 d.notifyObservers(
this);
514 template <
typename PropertyType>
547 template<
typename Property,
typename =
void>
556 { *
static_cast<T*
>(
value) =
static_cast<const Property *
>(
d)->value(); },
563 { observer->setSource(
static_cast<const Property *
>(
d)->bindingData()); },
564 []() {
return QMetaType::fromType<T>(); }
568 template<
typename Property>
577 { *
static_cast<T*
>(
value) =
static_cast<const Property *
>(
d)->value(); },
580 {
return static_cast<const Property *
>(
d)->binding(); },
585 { observer->setSource(
static_cast<const Property *
>(
d)->bindingData()); },
586 []() {
return QMetaType::fromType<T>(); }
590 template<
typename Property>
597 { *
static_cast<T*
>(
value) =
static_cast<const Property *
>(
d)->value(); },
601 {
return static_cast<const Property *
>(
d)->binding(); },
607 { observer->setSource(
static_cast<const Property *
>(
d)->bindingData()); },
608 []() {
return QMetaType::fromType<T>(); }
616 namespace BindableWarnings {
635 template<
typename Property>
676 template<
typename Functor>
684 template<
typename Functor>
691 template<
typename Functor>
799 template <
typename Functor>
802 std::enable_if_t<std::is_invocable_v<Functor>> * =
nullptr)
807 template <
typename Functor>
843 template<
typename Property,
typename =
typename Property::InheritsQUntypedPropertyData>
901 template <
typename Functor>
904 std::enable_if_t<std::is_invocable_v<Functor>> * =
nullptr)
909 template <
typename Functor>
928 template<
typename Functor>
934 template<
typename Functor>
940 template<
typename Functor>
952 template<
typename Class,
typename T, auto Offset, auto Signal =
nullptr>
956 static bool constexpr HasSignal = !std::is_same_v<decltype(Signal), std::nullptr_t>;
957 using SignalTakesValue = std::is_invocable<decltype(Signal),
Class,
T>;
960 char *that =
reinterpret_cast<char *
>(
this);
963 const Class *owner()
const
965 char *that =
const_cast<char *
>(
reinterpret_cast<const char *
>(
this));
971 if constexpr (HasSignal) {
975 (that->owner()->*Signal)();
991 template <
typename Functor>
993 typename std::enable_if_t<std::is_invocable_r_v<T, Functor&>> * =
nullptr)
997 template <
typename Functor>
1009 if constexpr (QTypeTraits::is_dereferenceable_v<T>) {
1011 }
else if constexpr (std::is_pointer_v<T>) {
1052 this->
val = std::move(
t);
1083 #ifndef Q_CLANG_QDOC
1084 template <
typename Functor>
1087 std::enable_if_t<std::is_invocable_v<Functor>> * =
nullptr)
1092 template <
typename Functor>
1099 return bd && bd->
binding() !=
nullptr;
1113 template<
typename Functor>
1116 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
1120 template<
typename Functor>
1123 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
1128 template<
typename Functor>
1131 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
1145 if constexpr (HasSignal) {
1149 (owner()->*Signal)();
1154 #define QT_OBJECT_BINDABLE_PROPERTY_3(Class, Type, name) \
1155 static constexpr size_t _qt_property_##name##_offset() { \
1156 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
1157 return offsetof(Class, name); \
1160 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name;
1162 #define QT_OBJECT_BINDABLE_PROPERTY_4(Class, Type, name, Signal) \
1163 static constexpr size_t _qt_property_##name##_offset() { \
1164 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
1165 return offsetof(Class, name); \
1168 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name;
1170 #define Q_OBJECT_BINDABLE_PROPERTY(...) \
1171 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
1172 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY, __VA_ARGS__) \
1175 #define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_4(Class, Type, name, value) \
1176 static constexpr size_t _qt_property_##name##_offset() \
1178 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
1179 return offsetof(Class, name); \
1182 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr> name = \
1183 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, nullptr>( \
1186 #define QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS_5(Class, Type, name, value, Signal) \
1187 static constexpr size_t _qt_property_##name##_offset() \
1189 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
1190 return offsetof(Class, name); \
1193 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal> name = \
1194 QObjectBindableProperty<Class, Type, Class::_qt_property_##name##_offset, Signal>( \
1197 #define Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(...) \
1198 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
1199 QT_OVERLOADED_MACRO(QT_OBJECT_BINDABLE_PROPERTY_WITH_ARGS, __VA_ARGS__) \
1202 template<
typename Class,
typename T, auto Offset, auto Getter>
1207 char *that =
reinterpret_cast<char *
>(
this);
1210 const Class *owner()
const
1212 char *that =
const_cast<char *
>(
reinterpret_cast<const char *
>(
this));
1225 return (owner()->*Getter)();
1228 std::conditional_t<QTypeTraits::is_dereferenceable_v<T>,
parameter_type,
void>
1231 if constexpr (QTypeTraits::is_dereferenceable_v<T>)
1249 template<
typename Functor>
1252 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
1256 template<
typename Functor>
1259 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
1264 template<
typename Functor>
1267 static_assert(std::is_invocable_v<Functor>,
"Functor callback must be callable without any parameters");
1286 #define Q_OBJECT_COMPUTED_PROPERTY(Class, Type, name, ...) \
1287 static constexpr size_t _qt_property_##name##_offset() { \
1288 QT_WARNING_PUSH QT_WARNING_DISABLE_INVALID_OFFSETOF \
1289 return offsetof(Class, name); \
1292 QObjectComputedProperty<Class, Type, Class::_qt_property_##name##_offset, __VA_ARGS__> name;
1294 #undef QT_SOURCE_LOCATION_NAMESPACE
small capitals from c petite p scientific i
[1]
QBindable is a wrapper class around binding-enabled properties. It allows type-safe operations while ...
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
void setValue(const T &value)
QPropertyBinding< T > makeBinding(const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
QPropertyBinding< T > takeBinding()
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &binding)
bool setBinding(const QUntypedPropertyBinding &binding)
QBindable(const QUntypedBindable &b)
QPropertyBinding< T > binding() const
QtPrivate::QPropertyBindingData * bindingData(const QUntypedPropertyData *data) const
void registerDependency(const QUntypedPropertyData *data) const
The QObjectBindableProperty class is a template class that enables automatic property bindings for pr...
QObjectBindableProperty & operator=(parameter_type newValue)
QObjectBindableProperty()=default
void setValue(parameter_type t)
QObjectBindableProperty & operator=(rvalue_ref newValue)
QPropertyNotifier addNotifier(Functor f)
QObjectBindableProperty(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, typename std::enable_if_t< std::is_invocable_r_v< T, Functor & >> *=nullptr)
QPropertyBinding< T > binding() const
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
arrow_operator_result operator->() const
parameter_type value() const
QObjectBindableProperty(T &&initialValue)
QPropertyChangeHandler< Functor > subscribe(Functor f)
void setValue(rvalue_ref t)
parameter_type operator*() const
QObjectBindableProperty(const QPropertyBinding< T > &binding)
typename QPropertyData< T >::parameter_type parameter_type
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &newBinding)
bool setBinding(const QUntypedPropertyBinding &newBinding)
QPropertyBinding< T > takeBinding()
QObjectBindableProperty(const T &initialValue)
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
const QtPrivate::QPropertyBindingData & bindingData() const
The QObjectComputedProperty class is a template class to help port old properties to the bindable pro...
constexpr bool hasBinding() const
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
QPropertyChangeHandler< Functor > subscribe(Functor f)
QObjectComputedProperty()=default
std::conditional_t< QTypeTraits::is_dereferenceable_v< T >, parameter_type, void > operator->() const
QtPrivate::QPropertyBindingData & bindingData() const
parameter_type operator*() const
parameter_type value() const
QPropertyNotifier addNotifier(Functor f)
QPropertyBinding< T > takeBinding()
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &newBinding)
QPropertyAlias< T > & operator=(const T &newValue)
bool setBinding(const QUntypedPropertyBinding &newBinding)
QPropertyAlias(Property *property)
QPropertyAlias(const QBindable< T > &property)
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
void setValue(const T &newValue)
QPropertyAlias(QProperty< T > *property)
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
QPropertyNotifier addNotifier(Functor f)
QPropertyAlias(QPropertyAlias< T > *alias)
QPropertyChangeHandler< Functor > subscribe(Functor f)
QPropertyBinding< T > binding() const
QPropertyBinding(const QUntypedPropertyBinding &binding)
QPropertyBinding()=default
QPropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location)
The QPropertyChangeHandler class controls the lifecycle of change callback installed on a QProperty.
QPropertyChangeHandler(Functor handler)
QPropertyChangeHandler(const Property &property, Functor handler)
The QPropertyData class is a helper class for properties with automatic property bindings.
QPropertyData(rvalue_ref t)
typename std::conditional_t< UseReferences, T &&, DisableRValueRefs > rvalue_ref
static constexpr bool UseReferences
std::conditional_t< UseReferences, const T &, T > parameter_type
void setValueBypassingBindings(rvalue_ref v)
std::conditional_t< std::is_pointer_v< T >, const T &, std::conditional_t< QTypeTraits::is_dereferenceable_v< T >, const T &, void > > arrow_operator_result
parameter_type valueBypassingBindings() const
void setValueBypassingBindings(parameter_type v)
QPropertyData(parameter_type t)
The QProperty class is a template class that enables automatic property bindings.
QPropertyBinding< T > takeBinding()
QProperty(const QPropertyBinding< T > &binding)
QPropertyChangeHandler< Functor > subscribe(Functor f)
QPropertyChangeHandler< Functor > onValueChanged(Functor f)
QProperty< T > & operator=(rvalue_ref newValue)
QProperty(rvalue_ref initialValue)
const QtPrivate::QPropertyBindingData & bindingData() const
bool setBinding(const QUntypedPropertyBinding &newBinding)
QProperty(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, typename std::enable_if_t< std::is_invocable_r_v< T, Functor & >> *=nullptr)
QPropertyBinding< T > binding() const
parameter_type value() const
QPropertyBinding< T > setBinding(const QPropertyBinding< T > &newBinding)
void setValue(parameter_type newValue)
void setValue(rvalue_ref newValue)
QProperty< T > & operator=(parameter_type newValue)
typename QPropertyData< T >::parameter_type parameter_type
QPropertyNotifier addNotifier(Functor f)
arrow_operator_result operator->() const
parameter_type operator*() const
QPropertyBinding< T > setBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
QProperty(parameter_type initialValue)
The QPropertyNotifier class controls the lifecycle of change callback installed on a QProperty.
QPropertyNotifier()=default
QPropertyNotifier(Functor handler)
QPropertyNotifier(const Property &property, Functor handler)
@ ObserverNotifiesBinding
@ ObserverNotifiesChangeHandler
QUntypedPropertyData * aliasData
void(*)(QPropertyObserver *, QUntypedPropertyData *) ChangeHandler
ChangeHandler changeHandler
QPropertyBindingPrivate * binding
void setSource(const Property &property)
QUntypedPropertyData * aliasedProperty() const
constexpr QPropertyObserver()=default
The QString class provides a Unicode character string.
QUntypedBindable is a uniform interface over bindable properties like QProperty<T> and QObjectBindabl...
QUntypedPropertyBinding binding() const
QUntypedPropertyBinding makeBinding(const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION) const
QMetaType metaType() const
const QtPrivate::QBindableInterface * iface
QPropertyChangeHandler< Functor > subscribe(Functor f) const
QUntypedPropertyBinding takeBinding()
bool setBinding(const QUntypedPropertyBinding &binding)
QUntypedBindable(Property *p)
QPropertyNotifier addNotifier(Functor f)
constexpr QUntypedBindable(QUntypedPropertyData *d, const QtPrivate::QBindableInterface *i)
QPropertyChangeHandler< Functor > onValueChanged(Functor f) const
constexpr QUntypedBindable()=default
void observe(QPropertyObserver *observer) const
QMetaType valueMetaType() const
QUntypedPropertyBinding()
QUntypedPropertyBinding(QMetaType metaType, Functor &&f, const QPropertyBindingSourceLocation &location)
static constexpr QBindableInterface iface
QUntypedPropertyBinding setBinding(const QUntypedPropertyBinding &newBinding, QUntypedPropertyData *propertyDataPtr, QPropertyObserverCallback staticObserverCallback=nullptr, QPropertyBindingWrapper bindingWrapper=nullptr)
QPropertyBindingPrivate * binding() const
auto it unsigned count const
typename C::value_type value_type
Q_CORE_EXPORT void beginPropertyUpdateGroup()
auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location=QT_PROPERTY_DEFAULT_BINDING_LOCATION, std::enable_if_t< std::is_invocable_v< Functor >> *=nullptr)
Q_CORE_EXPORT void endPropertyUpdateGroup()
void printMetaTypeMismatch(QMetaType actual, QMetaType expected)
void printUnsuitableBindableWarning(QAnyStringView prefix, BindableWarnings::Reason reason)
constexpr size_t getOffset(size_t o)
constexpr BindingFunctionVTable bindingFunctionVTable
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
EGLOutputLayerEXT EGLint EGLAttrib value
#define Q_DISABLE_COPY_MOVE(Class)
const QBindingStorage * qGetBindingStorage(const QObject *o)
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLenum GLsizei void GLsizei void * column
#define QT_PROPERTY_DEFAULT_BINDING_LOCATION
header setValue("Host", "qt-project.org")
QPropertyBindingSourceLocation()=default
QMetaType(*)() GetMetaType
void(*)(const QUntypedPropertyData *d, void *value) Getter
QUntypedPropertyBinding(*)(QUntypedPropertyData *d, const QUntypedPropertyBinding &binding) BindingSetter
void(*)(const QUntypedPropertyData *d, QPropertyObserver *observer) SetObserver
void(*)(QUntypedPropertyData *d, const void *value) Setter
QUntypedPropertyBinding(*)(const QUntypedPropertyData *d, const QPropertyBindingSourceLocation &location) MakeBinding
QUntypedPropertyBinding(*)(const QUntypedPropertyData *d) BindingGetter
static constexpr quintptr MetaTypeAccessorFlag