diff options
Diffstat (limited to 'src/concurrent/qtconcurrentrun.h')
-rw-r--r-- | src/concurrent/qtconcurrentrun.h | 139 |
1 files changed, 137 insertions, 2 deletions
diff --git a/src/concurrent/qtconcurrentrun.h b/src/concurrent/qtconcurrentrun.h index 4f583a343c..2f9b1b5e96 100644 --- a/src/concurrent/qtconcurrentrun.h +++ b/src/concurrent/qtconcurrentrun.h @@ -67,13 +67,108 @@ 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) { return (new StoredFunctionCall<Function, Args...>( - std::forward<Function>(f), std::forward<Args>(args)...)) - ->start(pool); + std::forward<Function>(f), std::forward<Args>(args)...))->start(pool); } template <class Function, class ...Args> @@ -83,6 +178,46 @@ auto run(Function &&f, Args &&...args) return run(QThreadPool::globalInstance(), std::forward<Function>(f), std::forward<Args>(args)...); } +template <class PromiseType, class Function, class ...Args> +[[nodiscard]] +auto runWithPromise(QThreadPool *pool, Function &&f, Args &&...args) +{ + return (new StoredFunctionCallWithPromise<Function, PromiseType, Args...>( + std::forward<Function>(f), std::forward<Args>(args)...))->start(pool); +} + +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; + return runWithPromise<PromiseType>(pool, std::forward<Function>(f), std::forward<Args>(args)...); +} + +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; + return runWithPromise<PromiseType>(pool, std::forward<const Function>(functionWrapper.get()), std::forward<Args>(args)...); +} + +template <class PromiseType, class Function, class ...Args> +[[nodiscard]] +auto runWithPromise(Function &&f, Args &&...args) +{ + return runWithPromise<PromiseType>(QThreadPool::globalInstance(), std::forward<Function>(f), std::forward<Args>(args)...); +} + +template <class Function, class ...Args> +[[nodiscard]] +auto runWithPromise(Function &&f, Args &&...args) +{ + return runWithPromise(QThreadPool::globalInstance(), std::forward<Function>(f), std::forward<Args>(args)...); +} + } //namespace QtConcurrent #endif // Q_CLANG_QDOC |