From ccd3b28aab33bd36f9c382cd38352f82396d25da Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 May 2023 09:50:11 +0200 Subject: [PATCH] Rename QFunctorSlotObject to QCallableObject After the recent changes we only have a single implementation of QSlotObjectBase, which can handle free functions, member functions, functors, and lambdas. Rename it to callable, and explicitly hide the static implementation function so that it doesn't become a symbol of static libraries using Qt. Also rename makeSlotObject to makeCallableObject, and polish coding style and comments in the qobjectdefs_impl header a bit. Change-Id: Id19107cedfe9c624f807cd8089beb80e9eb99f50 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qcoreapplication.h | 2 +- src/corelib/kernel/qobject.h | 2 +- src/corelib/kernel/qobjectdefs.h | 2 +- src/corelib/kernel/qobjectdefs_impl.h | 31 ++++++++++--------- src/corelib/kernel/qtimer.h | 2 +- src/network/kernel/qhostinfo.h | 2 +- .../corelib/kernel/qobject/tst_qobject.cpp | 6 ++-- 7 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index ae01cdee9a..37ed9890ed 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -128,7 +128,7 @@ public: using Prototype = void(*)(QPermission); QtPrivate::AssertCompatibleFunctions(); requestPermission(permission, - QtPrivate::makeSlotObject(std::forward(func)), + QtPrivate::makeCallableObject(std::forward(func)), receiver); } # endif // Q_QDOC diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 9cb025d20d..852f5c7053 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -230,7 +230,7 @@ public: pSlot = const_cast(reinterpret_cast(&slot)); return connectImpl(sender, reinterpret_cast(&signal), context, pSlot, - QtPrivate::makeSlotObject(std::forward(slot)), + QtPrivate::makeCallableObject(std::forward(slot)), type, types, &SignalType::Object::staticMetaObject); } diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index c79e02437f..1b074cea44 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -420,7 +420,7 @@ struct Q_CORE_EXPORT QMetaObject typename QtPrivate::Callable::ReturnType *ret = nullptr) { using Prototype = typename QtPrivate::Callable::Function; - return invokeMethodImpl(object, QtPrivate::makeSlotObject(std::forward(function)), type, ret); + return invokeMethodImpl(object, QtPrivate::makeCallableObject(std::forward(function)), type, ret); } template diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index f87b928263..9d9e024ce6 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -47,10 +47,11 @@ namespace QtPrivate { template struct List_Left { typedef List<> Value; }; /* - trick to set the return value of a slot that works even if the signal or the slot returns void - to be used like function(), ApplyReturnValue(&return_value) + Trick to set the return value of a slot that works even if the signal or the slot returns void + to be used like + function(), ApplyReturnValue(&return_value) if function() returns a value, the operator,(T, ApplyReturnValue) is called, but if it - returns void, the builtin one is used without an error. + returns void, the built-in one is used without an error. */ template struct ApplyReturnValue { @@ -80,7 +81,7 @@ namespace QtPrivate { and args is the array of pointer to arguments, as used in qt_metacall The Functor struct is the helper to call a functor of N argument. - its call function is the same as the FunctionPointer::call function. + Its call function is the same as the FunctionPointer::call function. */ template using InvokeGenSeq = typename T::Type; @@ -398,7 +399,7 @@ namespace QtPrivate { // internal base class (interface) containing functions required to call a slot managed by a pointer to function. class QSlotObjectBase { QAtomicInt m_ref; - // don't use virtual functions here; we don't want the + // Don't use virtual functions here; we don't want the // compiler to create tons of per-polymorphic-class stuff that // we'll never need. We just use one function pointer, and the // Operations enum below to distinguish requests @@ -422,7 +423,7 @@ namespace QtPrivate { { if (!m_ref.deref()) m_impl(Destroy, this, nullptr, nullptr, nullptr); } inline bool compare(void **a) { bool ret = false; m_impl(Compare, this, nullptr, a, &ret); return ret; } - inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, nullptr); } + inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, nullptr); } bool isImpl(ImplFn f) const { return m_impl == f; } protected: ~QSlotObjectBase() {} @@ -430,9 +431,9 @@ namespace QtPrivate { Q_DISABLE_COPY_MOVE(QSlotObjectBase) }; - // implementation of QSlotObjectBase for which the slot is a functor (or lambda) + // 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 QFunctorSlotObject : public QSlotObjectBase + template class QCallableObject : public QSlotObjectBase { using FunctorValue = std::decay_t; using FuncType = std::conditional_t, @@ -440,9 +441,9 @@ namespace QtPrivate { QtPrivate::Functor >; FunctorValue function; - static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) + Q_DECL_HIDDEN static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) { - const auto that = static_cast(this_); + const auto that = static_cast(this_); switch (which) { case Destroy: delete that; @@ -465,8 +466,8 @@ namespace QtPrivate { } } public: - explicit QFunctorSlotObject(Func &&f) : QSlotObjectBase(&impl), function(std::move(f)) {} - explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {} + explicit QCallableObject(Func &&f) : QSlotObjectBase(&impl), function(std::move(f)) {} + explicit QCallableObject(const Func &f) : QSlotObjectBase(&impl), function(f) {} }; // Helper to detect the context object type based on the functor type: @@ -508,7 +509,7 @@ namespace QtPrivate { template static constexpr std::enable_if_t() >= 0, QtPrivate::QSlotObjectBase *> - makeSlotObject(Functor &&func) + makeCallableObject(Functor &&func) { using ExpectedSignature = QtPrivate::FunctionPointer; using ExpectedReturnType = typename ExpectedSignature::ReturnType; @@ -521,14 +522,14 @@ namespace QtPrivate { static_assert(int(ActualSignature::ArgumentCount) <= int(ExpectedSignature::ArgumentCount), "Functor requires more arguments than what can be provided."); - return new QtPrivate::QFunctorSlotObject, ActualArguments, ExpectedReturnType>(std::forward(func)); + return new QtPrivate::QCallableObject, ActualArguments, ExpectedReturnType>(std::forward(func)); } template struct AreFunctionsCompatible : std::false_type {}; template struct AreFunctionsCompatible(std::forward(std::declval()))), + std::is_same_v(std::forward(std::declval()))), QtPrivate::QSlotObjectBase *>> > : std::true_type {}; diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 4c70ab2562..e77db27049 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -73,7 +73,7 @@ public: { using Prototype = void(*)(); singleShotImpl(interval, timerType, receiver, - QtPrivate::makeSlotObject(std::forward(slot))); + QtPrivate::makeCallableObject(std::forward(slot))); } // singleShot without context template diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h index 1f18bf8302..600e97d80a 100644 --- a/src/network/kernel/qhostinfo.h +++ b/src/network/kernel/qhostinfo.h @@ -68,7 +68,7 @@ public: using Prototype = void(*)(QHostInfo); QtPrivate::AssertCompatibleFunctions(); return lookupHostImpl(name, receiver, - QtPrivate::makeSlotObject(std::forward(func)), + QtPrivate::makeCallableObject(std::forward(func)), nullptr); } #endif // Q_QDOC diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index e721187b1e..16f53d58da 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -8387,7 +8387,7 @@ public: slotObject = nullptr; } QtPrivate::AssertCompatibleFunctions(); - slotObject = QtPrivate::makeSlotObject(std::forward(func)); + slotObject = QtPrivate::makeCallableObject(std::forward(func)); return true; } @@ -8405,7 +8405,7 @@ public: slotObject = nullptr; } QtPrivate::AssertCompatibleFunctions(); - slotObject = QtPrivate::makeSlotObject(std::forward(func)); + slotObject = QtPrivate::makeCallableObject(std::forward(func)); return true; } @@ -8544,7 +8544,7 @@ void tst_QObject::asyncCallbackHelper() QCOMPARE(result, QLatin1String(expectedPayload).length()); // mutable lambda; same behavior as mutableFunctor - we copy the functor - // in the QFunctorSlotObject, so the original is not modified + // in the QCallableObject, so the original is not modified int status = 0; auto mutableLambda1 = [&status, calls = 0]() mutable { status = ++calls; };