From 3c3de181ef7f82d205db312480bac3ce31c16e18 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 May 2023 15:51:55 +0200 Subject: [PATCH] QCallableObject: use QtPrivate::CompactStorage ... optimizing the storage of empty function objects. I thought we had applied this a long time ago, but it turns out that QPrivateSlotObject (c61d9873e5e30723bc5558b509b3320f2abf1da7) is only for QObjectPrivate::connect()... This adds the same optimization for regular QObject::connect(). This is BC, since we don't touch the base class (QSlotObjectBase), and the QCallableObject subclasses are all-inline or explicitly Q_DECL_HIDDEN. Amends c61d9873e5e30723bc5558b509b3320f2abf1da7. Change-Id: I63fd1b6f882b58f9f98eae67c636c3615248ad79 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobjectdefs_impl.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 8ae158b6b0c..72193cc9da3 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -12,6 +12,8 @@ #pragma qt_sync_stop_processing #endif +#include + QT_BEGIN_NAMESPACE class QObject; class QObjectPrivate; @@ -440,14 +442,16 @@ namespace QtPrivate { // Implementation of QSlotObjectBase for which the slot is a callable (function, PMF, functor, or lambda). // Args and R are the List of arguments and the return type of the signal to which the slot is connected. - template class QCallableObject : public QSlotObjectBase + template + class QCallableObject : public QSlotObjectBase, + private QtPrivate::CompactStorage> { using FunctorValue = std::decay_t; + using Storage = QtPrivate::CompactStorage; using FuncType = std::conditional_t, QtPrivate::FunctionPointer, QtPrivate::Functor >; - FunctorValue function; Q_DECL_HIDDEN static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) { const auto that = static_cast(this_); @@ -457,13 +461,13 @@ namespace QtPrivate { break; case Call: if constexpr (std::is_member_function_pointer_v) - FuncType::template call(that->function, static_cast(r), a); + FuncType::template call(that->object(), static_cast(r), a); else - FuncType::template call(that->function, r, a); + FuncType::template call(that->object(), r, a); break; case Compare: if constexpr (std::is_member_function_pointer_v) { - *ret = *reinterpret_cast(a) == that->function; + *ret = *reinterpret_cast(a) == that->object(); break; } // not implemented otherwise @@ -473,8 +477,8 @@ namespace QtPrivate { } } public: - explicit QCallableObject(Func &&f) : QSlotObjectBase(&impl), function(std::move(f)) {} - explicit QCallableObject(const Func &f) : QSlotObjectBase(&impl), function(f) {} + explicit QCallableObject(Func &&f) : QSlotObjectBase(&impl), Storage{std::move(f)} {} + explicit QCallableObject(const Func &f) : QSlotObjectBase(&impl), Storage{f} {} }; // Helper to detect the context object type based on the functor type: