summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfuture.h
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2021-11-04 17:01:54 +0100
committerSona Kurazyan <sona.kurazyan@qt.io>2021-11-20 10:28:29 +0100
commit102f7d31c469a546f52c930a047bd294fb198186 (patch)
tree45fe0355a7195e385b6b2457f79861bb7f3597bb /src/corelib/thread/qfuture.h
parent3b49aa72fe6ec0dd0aa0c1c41fb81e874dc789fa (diff)
Add support for combining multiple QFutures
[ChangeLog][QtCore] Added QtFuture::whenAll() and QtFuture::whenAny() functions, returning a QFuture that becomes ready when all or any of the supplied futures complete. Task-number: QTBUG-86714 Change-Id: I2bb7dbb4cdc4f79a7a4fd494142df6a0f93a2b39 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/thread/qfuture.h')
-rw-r--r--src/corelib/thread/qfuture.h84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/corelib/thread/qfuture.h b/src/corelib/thread/qfuture.h
index 094b3471b8..7aed38be16 100644
--- a/src/corelib/thread/qfuture.h
+++ b/src/corelib/thread/qfuture.h
@@ -314,6 +314,9 @@ private:
friend class QtPrivate::FailureHandler;
#endif
+ template<typename ResultType>
+ friend struct QtPrivate::WhenAnyContext;
+
using QFuturePrivate =
std::conditional_t<std::is_same_v<T, void>, QFutureInterfaceBase, QFutureInterface<T>>;
@@ -456,6 +459,87 @@ struct MetaTypeQFutureHelper<QFuture<T>>
} // namespace QtPrivate
+namespace QtFuture {
+
+#ifndef Q_CLANG_QDOC
+
+template<typename OutputSequence, typename InputIt,
+ typename ValueType = typename std::iterator_traits<InputIt>::value_type,
+ std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
+ QtPrivate::IsRandomAccessible<OutputSequence>,
+ QtPrivate::isQFuture<ValueType>>,
+ int> = 0>
+QFuture<OutputSequence> whenAll(InputIt first, InputIt last)
+{
+ return QtPrivate::whenAllImpl<OutputSequence, InputIt, ValueType>(first, last);
+}
+
+template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
+ std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
+ QtPrivate::isQFuture<ValueType>>,
+ int> = 0>
+QFuture<QList<ValueType>> whenAll(InputIt first, InputIt last)
+{
+ return QtPrivate::whenAllImpl<QList<ValueType>, InputIt, ValueType>(first, last);
+}
+
+template<typename OutputSequence, typename... Futures,
+ std::enable_if_t<std::conjunction_v<QtPrivate::IsRandomAccessible<OutputSequence>,
+ QtPrivate::NotEmpty<Futures...>,
+ QtPrivate::isQFuture<std::decay_t<Futures>>...>,
+ int> = 0>
+QFuture<OutputSequence> whenAll(Futures &&... futures)
+{
+ return QtPrivate::whenAllImpl<OutputSequence, Futures...>(std::forward<Futures>(futures)...);
+}
+
+template<typename... Futures,
+ std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
+ QtPrivate::isQFuture<std::decay_t<Futures>>...>,
+ int> = 0>
+QFuture<QList<std::variant<std::decay_t<Futures>...>>> whenAll(Futures &&... futures)
+{
+ return QtPrivate::whenAllImpl<QList<std::variant<std::decay_t<Futures>...>>, Futures...>(
+ std::forward<Futures>(futures)...);
+}
+
+template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
+ std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
+ QtPrivate::isQFuture<ValueType>>,
+ int> = 0>
+QFuture<WhenAnyResult<typename QtPrivate::Future<ValueType>::type>> whenAny(InputIt first,
+ InputIt last)
+{
+ return QtPrivate::whenAnyImpl<InputIt, ValueType>(first, last);
+}
+
+template<typename... Futures,
+ std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
+ QtPrivate::isQFuture<std::decay_t<Futures>>...>,
+ int> = 0>
+QFuture<std::variant<std::decay_t<Futures>...>> whenAny(Futures &&... futures)
+{
+ return QtPrivate::whenAnyImpl(std::forward<Futures>(futures)...);
+}
+
+#else
+
+template<typename OutputSequence, typename InputIt>
+QFuture<OutputSequence> whenAll(InputIt first, InputIt last);
+
+template<typename OutputSequence, typename... Futures>
+QFuture<OutputSequence> whenAll(Futures &&... futures);
+
+template<typename T, typename InputIt>
+QFuture<QtFuture::WhenAnyResult<T>> whenAny(InputIt first, InputIt last);
+
+template<typename... Futures>
+QFuture<std::variant<std::decay_t<Futures>...>> whenAny(Futures &&... futures);
+
+#endif // Q_CLANG_QDOC
+
+} // namespace QtFuture
+
Q_DECLARE_SEQUENTIAL_ITERATOR(Future)
QT_END_NAMESPACE