diff options
Diffstat (limited to 'src/corelib/kernel/qobjectdefs_impl.h')
-rw-r--r-- | src/corelib/kernel/qobjectdefs_impl.h | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 156a6d6c42..f87b928263 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -239,14 +239,6 @@ namespace QtPrivate { } }; - template<typename Function, int N> struct Functor - { - template <typename SignalArgs, typename R> - static void call(Function &f, void *, void **arg) { - FunctorCall<typename Indexes<N>::Value, SignalArgs, R, Function>::call(f, arg); - } - }; - // Traits to detect if there is a conversion between two types, // and that conversion does not include a narrowing conversion. template <typename T> @@ -335,6 +327,43 @@ namespace QtPrivate { typedef decltype(std::declval<Functor>().operator()((std::declval<ArgList>())...)) Value; }; + // Get the function prototype for a functor. There can only be one call operator + // in a functor, otherwise we get errors from ambiguity. But that's good enough. + template <typename Ret, typename... Args> + using FunctionTypeForTypes = Ret(*)(Args...); + + template <typename Ret, typename Obj, typename... Args> + FunctionTypeForTypes<Ret, Args...> FunctorPrototype(Ret(Obj::*)(Args...) const) { return nullptr; } + template <typename Ret, typename Obj, typename... Args> + FunctionTypeForTypes<Ret, Args...> FunctorPrototype(Ret(Obj::*)(Args...)) { return nullptr; } + template <typename Ret, typename Obj, typename... Args> + FunctionTypeForTypes<Ret, Args...> FunctorPrototype(Ret(Obj::*)(Args...) const noexcept) { return nullptr; } + template <typename Ret, typename Obj, typename... Args> + FunctionTypeForTypes<Ret, Args...> FunctorPrototype(Ret(Obj::*)(Args...) noexcept) { return nullptr; } + + template<typename Function, int N> struct Functor + { + template <typename SignalArgs, typename R> + static void call(Function &f, void *, void **arg) { + FunctorCall<typename Indexes<N>::Value, SignalArgs, R, Function>::call(f, arg); + } + }; + + template<typename Func> + struct ZeroArgFunctor : Functor<Func, 0> + { + using Function = decltype(FunctorPrototype(&std::decay_t<Func>::operator())); + enum {ArgumentCount = 0}; + using Arguments = QtPrivate::List<>; + using ReturnType = typename FunctionPointer<Function>::ReturnType; + }; + + template<typename Func> + using Callable = std::conditional_t<FunctionPointer<Func>::ArgumentCount == -1, + ZeroArgFunctor<Func>, + FunctionPointer<Func> + >; + /* Wrapper around ComputeFunctorArgumentCount and CheckCompatibleArgument, depending on whether \a Functor is a PMF or not. Returns -1 if \a Func is @@ -440,19 +469,6 @@ namespace QtPrivate { explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {} }; - // typedefs for readability for when there are no parameters - template <typename Func> - using QSlotObjectWithNoArgs = QFunctorSlotObject<Func, - QtPrivate::List<>, - typename QtPrivate::FunctionPointer<Func>::ReturnType>; - - template <typename Func, typename R> - using QFunctorSlotObjectWithNoArgs = QFunctorSlotObject<Func, QtPrivate::List<>, R>; - - template <typename Func> - using QFunctorSlotObjectWithNoArgsImplicitReturn = QFunctorSlotObjectWithNoArgs<Func, typename QtPrivate::FunctionPointer<Func>::ReturnType>; - - // Helper to detect the context object type based on the functor type: // QObject for free functions and lambdas; the callee for member function // pointers. The default declaration doesn't have the ContextType typedef, |