diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-11-04 17:01:54 +0100 |
---|---|---|
committer | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-11-20 10:28:29 +0100 |
commit | 102f7d31c469a546f52c930a047bd294fb198186 (patch) | |
tree | 45fe0355a7195e385b6b2457f79861bb7f3597bb /src/corelib/thread/qfuture.h | |
parent | 3b49aa72fe6ec0dd0aa0c1c41fb81e874dc789fa (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.h | 84 |
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 |