From ed546ff216010c979b94263aab4773a1a6afd5bb Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Thu, 9 Dec 2021 21:49:40 +0100 Subject: QtFuture::connect: exclude QPrivateSignal from the resulting future type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: MÃ¥rten Nordheim Reviewed-by: Qt CI Bot --- src/corelib/thread/qfuture_impl.h | 52 +++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'src') 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>; }; +// Helpers to remove QPrivateSignal argument from the list of arguments + +template +inline constexpr bool IsPrivateSignalArg = false; + +template +inline constexpr bool IsPrivateSignalArg + >> = true; + +template +auto cutTuple(Tuple &&t, std::index_sequence) +{ + return std::make_tuple(std::get(t)...); +} + +template +auto createTuple(Arg &&arg, Args &&... args) +{ + using TupleType = std::tuple, std::decay_t...>; + constexpr auto Size = sizeof...(Args); // One less than the size of all arguments + if constexpr (QtPrivate::IsPrivateSignalArg>) { + if constexpr (Size == 1) { + return arg; + } else { + return cutTuple(std::make_tuple(std::forward(arg), std::forward(args)...), + std::make_index_sequence()); + } + } else { + return std::make_tuple(std::forward(arg), std::forward(args)...); + } +} + // Helpers to resolve argument types of callables. + +template +using FilterLastPrivateSignalArg = + std::conditional_t<(sizeof...(Args) > 0), + std::invoke_result_t), Arg, Args...>, + std::conditional_t, void, Arg>>; + template struct ArgsType; @@ -140,9 +181,7 @@ struct ArgsType using PromiseType = void; using IsPromise = std::false_type; static const bool HasExtraArgs = (sizeof...(Args) > 0); - using AllArgs = - std::conditional_t, std::decay_t...>, - std::decay_t>; + using AllArgs = FilterLastPrivateSignalArg, std::decay_t...>; template static const bool CanInvokeWithArgs = std::is_invocable_v; @@ -155,9 +194,7 @@ struct ArgsType &, Args...> using PromiseType = Arg; using IsPromise = std::true_type; static const bool HasExtraArgs = (sizeof...(Args) > 0); - using AllArgs = - std::conditional_t &>, std::decay_t...>, - std::decay_t &>>; + using AllArgs = FilterLastPrivateSignalArg, std::decay_t...>; template static const bool CanInvokeWithArgs = std::is_invocable_v &, Args...>; @@ -899,7 +936,8 @@ static QFuture> 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 { -- cgit v1.2.3