diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-12-09 21:49:40 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@qt.io> | 2021-12-11 21:47:17 +0000 |
commit | ed546ff216010c979b94263aab4773a1a6afd5bb (patch) | |
tree | 33fdeb92d1bf4787d81828e17776c49eb9c0956c /src/corelib/thread | |
parent | 799660d679e5cc1638d403a19871534627e17dc6 (diff) |
QtFuture::connect: exclude QPrivateSignal from the resulting future type
Filter out the last argument of type QPrivateSignal from the signal's
arguments passed to QtFuture::connect().
Pick-to: 6.2
Fixes: QTBUG-92501
Change-Id: Idcd6baba1f01fcc94fa64b1c7030a629d01ed7a1
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qfuture_impl.h | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/corelib/thread/qfuture_impl.h b/src/corelib/thread/qfuture_impl.h index 136892ddaf..869a791b15 100644 --- a/src/corelib/thread/qfuture_impl.h +++ b/src/corelib/thread/qfuture_impl.h @@ -129,7 +129,48 @@ struct ResultTypeHelper< using ResultType = std::invoke_result_t<std::decay_t<F>>; }; +// Helpers to remove QPrivateSignal argument from the list of arguments + +template<class T, class Enable = void> +inline constexpr bool IsPrivateSignalArg = false; + +template<class T> +inline constexpr bool IsPrivateSignalArg<T, typename std::enable_if_t< + // finds injected-class-name, the 'class' avoids falling into the rules of [class.qual]/2: + std::is_class_v<class T::QPrivateSignal> + >> = true; + +template<class Tuple, std::size_t... I> +auto cutTuple(Tuple &&t, std::index_sequence<I...>) +{ + return std::make_tuple(std::get<I>(t)...); +} + +template<class Arg, class... Args> +auto createTuple(Arg &&arg, Args &&... args) +{ + using TupleType = std::tuple<std::decay_t<Arg>, std::decay_t<Args>...>; + constexpr auto Size = sizeof...(Args); // One less than the size of all arguments + if constexpr (QtPrivate::IsPrivateSignalArg<std::tuple_element_t<Size, TupleType>>) { + if constexpr (Size == 1) { + return arg; + } else { + return cutTuple(std::make_tuple(std::forward<Arg>(arg), std::forward<Args>(args)...), + std::make_index_sequence<Size>()); + } + } else { + return std::make_tuple(std::forward<Arg>(arg), std::forward<Args>(args)...); + } +} + // Helpers to resolve argument types of callables. + +template<class Arg, class... Args> +using FilterLastPrivateSignalArg = + std::conditional_t<(sizeof...(Args) > 0), + std::invoke_result_t<decltype(createTuple<Arg, Args...>), Arg, Args...>, + std::conditional_t<IsPrivateSignalArg<Arg>, void, Arg>>; + template<typename...> struct ArgsType; @@ -140,9 +181,7 @@ struct ArgsType<Arg, Args...> using PromiseType = void; using IsPromise = std::false_type; static const bool HasExtraArgs = (sizeof...(Args) > 0); - using AllArgs = - std::conditional_t<HasExtraArgs, std::tuple<std::decay_t<Arg>, std::decay_t<Args>...>, - std::decay_t<Arg>>; + using AllArgs = FilterLastPrivateSignalArg<std::decay_t<Arg>, std::decay_t<Args>...>; template<class Class, class Callable> static const bool CanInvokeWithArgs = std::is_invocable_v<Callable, Class, Arg, Args...>; @@ -155,9 +194,7 @@ struct ArgsType<QPromise<Arg> &, Args...> using PromiseType = Arg; using IsPromise = std::true_type; 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> &>>; + using AllArgs = FilterLastPrivateSignalArg<QPromise<Arg>, std::decay_t<Args>...>; template<class Class, class Callable> static const bool CanInvokeWithArgs = std::is_invocable_v<Callable, Class, QPromise<Arg> &, Args...>; @@ -899,7 +936,8 @@ static QFuture<ArgsType<Signal>> connect(Sender *sender, Signal signal) [promise, connections](auto... values) mutable { QObject::disconnect(connections->first); QObject::disconnect(connections->second); - promise.reportResult(std::make_tuple(values...)); + promise.reportResult(QtPrivate::createTuple( + std::move(values)...)); promise.reportFinished(); }); } else { |