summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qproperty.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-07-08 10:57:21 +0200
committerLars Knoll <lars.knoll@qt.io>2020-07-10 15:07:07 +0200
commitbe1ce6b26909256e62c2b39e4de9f8f79d070937 (patch)
tree56ae09231c362010b17df127c4d7c17ab4943f30 /src/corelib/kernel/qproperty.h
parent0d1208f0f08727c55de9eed8e0ceef092080b927 (diff)
Separate the error case when evaluating bindings
There's no point in returning a usually empty error when evaluating bindings, adding overhead to the regular code path. Instead, the error can be set on the currently evaluating binding if required. This streamlines the functor used to wrap the binding and should thus expand to less code and execute faster in the regular case. To achieve this, expose a pointer to the currently evaluating binding in the private API (as QtQml needs it to be able to report errors). The error case now requires one additional TLS lookup, but we don't really care about performance in that case anyway. Change-Id: Iecb450e765244930a41d813fcf8eb4013957a6a3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel/qproperty.h')
-rw-r--r--src/corelib/kernel/qproperty.h33
1 files changed, 5 insertions, 28 deletions
diff --git a/src/corelib/kernel/qproperty.h b/src/corelib/kernel/qproperty.h
index 986c6afbc9..8a712d395e 100644
--- a/src/corelib/kernel/qproperty.h
+++ b/src/corelib/kernel/qproperty.h
@@ -119,9 +119,8 @@ private:
class Q_CORE_EXPORT QUntypedPropertyBinding
{
public:
- using BindingEvaluationResult = QPropertyBindingError;
// writes binding result into dataPtr
- using BindingEvaluationFunction = std::function<BindingEvaluationResult(const QMetaType &metaType, void *dataPtr)>;
+ using BindingEvaluationFunction = std::function<void(const QMetaType &metaType, void *dataPtr)>;
QUntypedPropertyBinding();
QUntypedPropertyBinding(const QMetaType &metaType, BindingEvaluationFunction function, const QPropertyBindingSourceLocation &location);
@@ -152,19 +151,10 @@ class QPropertyBinding : public QUntypedPropertyBinding
struct BindingAdaptor
{
Functor impl;
- QUntypedPropertyBinding::BindingEvaluationResult operator()(const QMetaType &/*metaType*/, void *dataPtr)
+ void operator()(const QMetaType &/*metaType*/, void *dataPtr)
{
- std::variant<PropertyType, QPropertyBindingError> result(impl());
- if (auto errorPtr = std::get_if<QPropertyBindingError>(&result))
- return *errorPtr;
-
- if (auto valuePtr = std::get_if<PropertyType>(&result)) {
- PropertyType *propertyPtr = reinterpret_cast<PropertyType *>(dataPtr);
- *propertyPtr = std::move(*valuePtr);
- return {};
- }
-
- return {};
+ PropertyType *propertyPtr = static_cast<PropertyType *>(dataPtr);
+ *propertyPtr = impl();
}
};
@@ -191,25 +181,12 @@ public:
{}
};
-namespace QtPrivate {
- template<typename... Ts>
- constexpr auto is_variant_v = false;
- template<typename... Ts>
- constexpr auto is_variant_v<std::variant<Ts...>> = true;
-}
-
namespace Qt {
template <typename Functor>
auto makePropertyBinding(Functor &&f, const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION,
std::enable_if_t<std::is_invocable_v<Functor>> * = 0)
{
- if constexpr (QtPrivate::is_variant_v<std::invoke_result_t<Functor>>) {
- return QPropertyBinding<std::variant_alternative_t<0, std::invoke_result_t<Functor>>>(std::forward<Functor>(f), location);
- } else {
- return QPropertyBinding<std::invoke_result_t<Functor>>(std::forward<Functor>(f), location);
- }
- // Work around bogus warning
- Q_UNUSED(QtPrivate::is_variant_v<bool>);
+ return QPropertyBinding<std::invoke_result_t<Functor>>(std::forward<Functor>(f), location);
}
}