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 <thiago.macieira@intel.com>
This commit is contained in:
Volker Hilsheimer 2023-05-05 09:50:11 +02:00
parent 0306247f5a
commit ccd3b28aab
7 changed files with 24 additions and 23 deletions

View File

@ -128,7 +128,7 @@ public:
using Prototype = void(*)(QPermission);
QtPrivate::AssertCompatibleFunctions<Prototype, Functor>();
requestPermission(permission,
QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(func)),
QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(func)),
receiver);
}
# endif // Q_QDOC

View File

@ -230,7 +230,7 @@ public:
pSlot = const_cast<void **>(reinterpret_cast<void *const *>(&slot));
return connectImpl(sender, reinterpret_cast<void **>(&signal), context, pSlot,
QtPrivate::makeSlotObject<Func1>(std::forward<Func2>(slot)),
QtPrivate::makeCallableObject<Func1>(std::forward<Func2>(slot)),
type, types, &SignalType::Object::staticMetaObject);
}

View File

@ -420,7 +420,7 @@ struct Q_CORE_EXPORT QMetaObject
typename QtPrivate::Callable<Func>::ReturnType *ret = nullptr)
{
using Prototype = typename QtPrivate::Callable<Func>::Function;
return invokeMethodImpl(object, QtPrivate::makeSlotObject<Prototype>(std::forward<Func>(function)), type, ret);
return invokeMethodImpl(object, QtPrivate::makeCallableObject<Prototype>(std::forward<Func>(function)), type, ret);
}
template <typename Func>

View File

@ -47,10 +47,11 @@ namespace QtPrivate {
template <typename L> struct List_Left<L, 0> { 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<ReturnType>(&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<ReturnType>(&return_value)
if function() returns a value, the operator,(T, ApplyReturnValue<ReturnType>) 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 <typename T>
struct ApplyReturnValue {
@ -80,7 +81,7 @@ namespace QtPrivate {
and args is the array of pointer to arguments, as used in qt_metacall
The Functor<Func,N> 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<class T> 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<typename Func, typename Args, typename R> class QFunctorSlotObject : public QSlotObjectBase
template<typename Func, typename Args, typename R> class QCallableObject : public QSlotObjectBase
{
using FunctorValue = std::decay_t<Func>;
using FuncType = std::conditional_t<std::is_member_function_pointer_v<FunctorValue>,
@ -440,9 +441,9 @@ namespace QtPrivate {
QtPrivate::Functor<FunctorValue, Args::size>
>;
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<QFunctorSlotObject*>(this_);
const auto that = static_cast<QCallableObject*>(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 <typename Prototype, typename Functor>
static constexpr std::enable_if_t<QtPrivate::countMatchingArguments<Prototype, Functor>() >= 0,
QtPrivate::QSlotObjectBase *>
makeSlotObject(Functor &&func)
makeCallableObject(Functor &&func)
{
using ExpectedSignature = QtPrivate::FunctionPointer<Prototype>;
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<std::decay_t<Functor>, ActualArguments, ExpectedReturnType>(std::forward<Functor>(func));
return new QtPrivate::QCallableObject<std::decay_t<Functor>, ActualArguments, ExpectedReturnType>(std::forward<Functor>(func));
}
template<typename Prototype, typename Functor, typename = void>
struct AreFunctionsCompatible : std::false_type {};
template<typename Prototype, typename Functor>
struct AreFunctionsCompatible<Prototype, Functor, std::enable_if_t<
std::is_same_v<decltype(QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(std::declval<Functor>()))),
std::is_same_v<decltype(QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(std::declval<Functor>()))),
QtPrivate::QSlotObjectBase *>>
> : std::true_type {};

View File

@ -73,7 +73,7 @@ public:
{
using Prototype = void(*)();
singleShotImpl(interval, timerType, receiver,
QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(slot)));
QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(slot)));
}
// singleShot without context
template <typename Duration, typename Functor>

View File

@ -68,7 +68,7 @@ public:
using Prototype = void(*)(QHostInfo);
QtPrivate::AssertCompatibleFunctions<Prototype, Functor>();
return lookupHostImpl(name, receiver,
QtPrivate::makeSlotObject<Prototype>(std::forward<Functor>(func)),
QtPrivate::makeCallableObject<Prototype>(std::forward<Functor>(func)),
nullptr);
}
#endif // Q_QDOC

View File

@ -8387,7 +8387,7 @@ public:
slotObject = nullptr;
}
QtPrivate::AssertCompatibleFunctions<Prototype0, Functor>();
slotObject = QtPrivate::makeSlotObject<Prototype0>(std::forward<Functor>(func));
slotObject = QtPrivate::makeCallableObject<Prototype0>(std::forward<Functor>(func));
return true;
}
@ -8405,7 +8405,7 @@ public:
slotObject = nullptr;
}
QtPrivate::AssertCompatibleFunctions<Prototype1, Functor>();
slotObject = QtPrivate::makeSlotObject<Prototype1>(std::forward<Functor>(func));
slotObject = QtPrivate::makeCallableObject<Prototype1>(std::forward<Functor>(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; };