diff options
-rw-r--r-- | src/concurrent/qtconcurrentrun.h | 104 | ||||
-rw-r--r-- | src/corelib/thread/qfuture_impl.h | 46 |
2 files changed, 50 insertions, 100 deletions
diff --git a/src/concurrent/qtconcurrentrun.h b/src/concurrent/qtconcurrentrun.h index 5804393e25..79322b925f 100644 --- a/src/concurrent/qtconcurrentrun.h +++ b/src/concurrent/qtconcurrentrun.h @@ -73,102 +73,6 @@ namespace QtConcurrent { namespace QtConcurrent { -// Note: It's a copy taken from qfuture_impl.h with some specialization added -// TODO: Get rid of the code repetition and unify this for both purposes, see QTBUG-83331 -template<typename...> -struct ArgsType; - -template<typename Arg, typename... Args> -struct ArgsType<Arg, Args...> -{ - using PromiseType = void; - static const bool IsPromise = false; -}; - -// Note: this specialization was added -template<typename Arg, typename... Args> -struct ArgsType<QPromise<Arg> &, Args...> -{ - using PromiseType = Arg; - static const bool IsPromise = true; -}; - -template<> -struct ArgsType<> -{ - using PromiseType = void; - static const bool IsPromise = false; -}; - -template<typename F> -struct ArgResolver : ArgResolver<decltype(&std::decay_t<F>::operator())> -{ -}; - -// Note: this specialization was added, see callableObjectWithState() test in qtconcurrentrun -template<typename F> -struct ArgResolver<std::reference_wrapper<F>> : ArgResolver<decltype(&std::decay_t<F>::operator())> -{ -}; - -template<typename R, typename... Args> -struct ArgResolver<R(Args...)> : public ArgsType<Args...> -{ -}; - -template<typename R, typename... Args> -struct ArgResolver<R (*)(Args...)> : public ArgsType<Args...> -{ -}; - -// Note: this specialization was added, see light() test in qtconcurrentrun -template<typename R, typename... Args> -struct ArgResolver<R (*&)(Args...)> : public ArgsType<Args...> -{ -}; - -// Note: this specialization was added, see light() test in qtconcurrentrun -template<typename R, typename... Args> -struct ArgResolver<R (* const)(Args...)> : public ArgsType<Args...> -{ -}; - -template<typename R, typename... Args> -struct ArgResolver<R (&)(Args...)> : public ArgsType<Args...> -{ -}; - -template<typename Class, typename R, typename... Args> -struct ArgResolver<R (Class::*)(Args...)> : public ArgsType<Args...> -{ -}; - -template<typename Class, typename R, typename... Args> -struct ArgResolver<R (Class::*)(Args...) noexcept> : public ArgsType<Args...> -{ -}; - -template<typename Class, typename R, typename... Args> -struct ArgResolver<R (Class::*)(Args...) const> : public ArgsType<Args...> -{ -}; - -template<typename Class, typename R, typename... Args> -struct ArgResolver<R (Class::*)(Args...) const noexcept> : public ArgsType<Args...> -{ -}; - -// Note: this specialization was added, see crefFunction() test in qtconcurrentrun -template<typename Class, typename R, typename... Args> -struct ArgResolver<R (Class::* const)(Args...) const> : public ArgsType<Args...> -{ -}; - -template<typename Class, typename R, typename... Args> -struct ArgResolver<R (Class::* const)(Args...) const noexcept> : public ArgsType<Args...> -{ -}; - template <class Function, class ...Args> [[nodiscard]] auto run(QThreadPool *pool, Function &&f, Args &&...args) @@ -196,8 +100,8 @@ template <class Function, class ...Args> [[nodiscard]] auto runWithPromise(QThreadPool *pool, Function &&f, Args &&...args) { - static_assert(ArgResolver<Function>::IsPromise, "The first argument of passed callable object isn't a QPromise<T> & type."); - using PromiseType = typename ArgResolver<Function>::PromiseType; + static_assert(QtPrivate::ArgResolver<Function>::IsPromise, "The first argument of passed callable object isn't a QPromise<T> & type."); + using PromiseType = typename QtPrivate::ArgResolver<Function>::PromiseType; return runWithPromise<PromiseType>(pool, std::forward<Function>(f), std::forward<Args>(args)...); } @@ -205,8 +109,8 @@ template <class Function, class ...Args> [[nodiscard]] auto runWithPromise(QThreadPool *pool, std::reference_wrapper<const Function> &&functionWrapper, Args &&...args) { - static_assert(ArgResolver<const Function>::IsPromise, "The first argument of passed callable object isn't a QPromise<T> & type."); - using PromiseType = typename ArgResolver<const Function>::PromiseType; + static_assert(QtPrivate::ArgResolver<const Function>::IsPromise, "The first argument of passed callable object isn't a QPromise<T> & type."); + using PromiseType = typename QtPrivate::ArgResolver<const Function>::PromiseType; return runWithPromise<PromiseType>(pool, std::forward<const Function>(functionWrapper.get()), std::forward<Args>(args)...); } diff --git a/src/corelib/thread/qfuture_impl.h b/src/corelib/thread/qfuture_impl.h index 883f8d4f09..bd3976f990 100644 --- a/src/corelib/thread/qfuture_impl.h +++ b/src/corelib/thread/qfuture_impl.h @@ -59,6 +59,8 @@ template<class T> class QFuture; template<class T> class QFutureInterface; +template<class T> +class QPromise; namespace QtFuture { enum class Launch { Sync, Async, Inherit }; @@ -121,6 +123,8 @@ template<typename Arg, typename... Args> struct ArgsType<Arg, Args...> { using First = Arg; + using PromiseType = void; + static const bool IsPromise = false; static const bool HasExtraArgs = (sizeof...(Args) > 0); using AllArgs = std::conditional_t<HasExtraArgs, std::tuple<std::decay_t<Arg>, std::decay_t<Args>...>, @@ -130,10 +134,27 @@ struct ArgsType<Arg, Args...> static const bool CanInvokeWithArgs = std::is_invocable_v<Callable, Class, Arg, Args...>; }; +template<typename Arg, typename... Args> +struct ArgsType<QPromise<Arg> &, Args...> +{ + using First = QPromise<Arg> &; + using PromiseType = Arg; + static const bool IsPromise = true; + static const bool HasExtraArgs = (sizeof...(Args) > 0); + using AllArgs = + std::conditional_t<HasExtraArgs, std::tuple<std::decay_t<QPromise<Arg> &>, std::decay_t<Args>...>, + std::decay_t<QPromise<Arg> &>>; + + template<class Class, class Callable> + static const bool CanInvokeWithArgs = std::is_invocable_v<Callable, Class, QPromise<Arg> &, Args...>; +}; + template<> struct ArgsType<> { using First = void; + using PromiseType = void; + static const bool IsPromise = false; static const bool HasExtraArgs = false; using AllArgs = void; @@ -146,6 +167,11 @@ struct ArgResolver : ArgResolver<decltype(&std::decay_t<F>::operator())> { }; +template<typename F> +struct ArgResolver<std::reference_wrapper<F>> : ArgResolver<decltype(&std::decay_t<F>::operator())> +{ +}; + template<typename R, typename... Args> struct ArgResolver<R(Args...)> : public ArgsType<Args...> { @@ -157,6 +183,16 @@ struct ArgResolver<R (*)(Args...)> : public ArgsType<Args...> }; template<typename R, typename... Args> +struct ArgResolver<R (*&)(Args...)> : public ArgsType<Args...> +{ +}; + +template<typename R, typename... Args> +struct ArgResolver<R (* const)(Args...)> : public ArgsType<Args...> +{ +}; + +template<typename R, typename... Args> struct ArgResolver<R (&)(Args...)> : public ArgsType<Args...> { }; @@ -181,6 +217,16 @@ struct ArgResolver<R (Class::*)(Args...) const noexcept> : public ArgsType<Args. { }; +template<typename Class, typename R, typename... Args> +struct ArgResolver<R (Class::* const)(Args...) const> : public ArgsType<Args...> +{ +}; + +template<typename Class, typename R, typename... Args> +struct ArgResolver<R (Class::* const)(Args...) const noexcept> : public ArgsType<Args...> +{ +}; + template<class Class, class Callable> using EnableIfInvocable = std::enable_if_t< QtPrivate::ArgResolver<Callable>::template CanInvokeWithArgs<Class, Callable>>; |