summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2021-12-09 21:49:40 +0100
committerMarc Mutz <marc.mutz@qt.io>2021-12-11 21:47:17 +0000
commited546ff216010c979b94263aab4773a1a6afd5bb (patch)
tree33fdeb92d1bf4787d81828e17776c49eb9c0956c /src/corelib/thread
parent799660d679e5cc1638d403a19871534627e17dc6 (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.h52
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 {