QtConcurrent: Reuse ArgResolver from qfuture_impl.h
Task-number: QTBUG-83331 Change-Id: I572f68f6d3be4a50970d8d77d070f175be3ec785 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
parent
0807ede08c
commit
c91327645b
@ -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)...);
|
||||
}
|
||||
|
||||
|
@ -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...>
|
||||
{
|
||||
@ -156,6 +182,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>>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user