File indexing completed on 2025-10-16 09:03:42
0001
0002
0003
0004 #ifndef QFUTURE_H
0005 #define QFUTURE_H
0006
0007 #include <QtCore/qglobal.h>
0008
0009 #include <QtCore/qfutureinterface.h>
0010 #include <QtCore/qmetatype.h>
0011 #include <QtCore/qstring.h>
0012
0013 #include <QtCore/qfuture_impl.h>
0014
0015 #include <type_traits>
0016
0017 QT_REQUIRE_CONFIG(future);
0018
0019 QT_BEGIN_NAMESPACE
0020
0021 template <typename T>
0022 class QFutureWatcher;
0023
0024 template <typename T>
0025 class QFuture
0026 {
0027 static_assert (std::is_move_constructible_v<T>
0028 || std::is_same_v<T, void>,
0029 "A move-constructible type or type void is required");
0030 public:
0031 QFuture()
0032 : d(QFutureInterface<T>::canceledResult())
0033 { }
0034
0035 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
0036 explicit QFuture(QFutureInterface<T> *p)
0037 : d(*p)
0038 { }
0039
0040 template<typename U = T, typename = QtPrivate::EnableForVoid<U>>
0041 explicit QFuture(QFutureInterfaceBase *p)
0042 : d(*p)
0043 {
0044 }
0045
0046 template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
0047 explicit QFuture(const QFuture<U> &other) : d(other.d)
0048 {
0049 }
0050
0051 template<typename U, typename V = T, typename = QtPrivate::EnableForVoid<V>>
0052 QFuture<void> &operator=(const QFuture<U> &other)
0053 {
0054 d = other.d;
0055 return *this;
0056 }
0057
0058 #if defined(Q_QDOC)
0059 ~QFuture() { }
0060 QFuture(const QFuture<T> &) { }
0061 QFuture<T> & operator=(const QFuture<T> &) { }
0062 #endif
0063
0064 void cancel() { d.cancel(); }
0065 bool isCanceled() const { return d.isCanceled(); }
0066
0067 #if QT_DEPRECATED_SINCE(6, 0)
0068 QT_DEPRECATED_VERSION_X_6_0("Use setSuspended() instead.")
0069 void setPaused(bool paused) { d.setSuspended(paused); }
0070
0071 QT_DEPRECATED_VERSION_X_6_0("Use isSuspending() or isSuspended() instead.")
0072 bool isPaused() const
0073 {
0074 QT_WARNING_PUSH
0075 QT_WARNING_DISABLE_DEPRECATED
0076 return d.isPaused();
0077 QT_WARNING_POP
0078 }
0079
0080 QT_DEPRECATED_VERSION_X_6_0("Use toggleSuspended() instead.")
0081 void togglePaused() { d.toggleSuspended(); }
0082
0083 QT_DEPRECATED_VERSION_X_6_0("Use suspend() instead.")
0084 void pause() { suspend(); }
0085 #endif
0086 bool isSuspending() const { return d.isSuspending(); }
0087 bool isSuspended() const { return d.isSuspended(); }
0088 void setSuspended(bool suspend) { d.setSuspended(suspend); }
0089 void suspend() { setSuspended(true); }
0090 void resume() { setSuspended(false); }
0091 void toggleSuspended() { d.toggleSuspended(); }
0092
0093 bool isStarted() const { return d.isStarted(); }
0094 bool isFinished() const { return d.isFinished(); }
0095 bool isRunning() const { return d.isRunning(); }
0096
0097 int resultCount() const { return d.resultCount(); }
0098 int progressValue() const { return d.progressValue(); }
0099 int progressMinimum() const { return d.progressMinimum(); }
0100 int progressMaximum() const { return d.progressMaximum(); }
0101 QString progressText() const { return d.progressText(); }
0102 void waitForFinished() { d.waitForFinished(); }
0103
0104 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
0105 inline T result() const;
0106
0107 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
0108 inline T resultAt(int index) const;
0109
0110 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
0111 bool isResultReadyAt(int resultIndex) const { return d.isResultReadyAt(resultIndex); }
0112
0113 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
0114 QList<T> results() const { return d.results(); }
0115
0116 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
0117 T takeResult() { return d.takeResult(); }
0118
0119 #if 0
0120
0121 template<typename U = T, typename = QtPrivate::EnableForNonVoid<U>>
0122 std::vector<T> takeResults() { return d.takeResults(); }
0123 #endif
0124
0125 bool isValid() const { return d.isValid(); }
0126
0127 template<class Function>
0128 using ResultType = typename QtPrivate::ResultTypeHelper<Function, T>::ResultType;
0129
0130 template<class Function>
0131 QFuture<ResultType<Function>> then(Function &&function);
0132
0133 template<class Function>
0134 QFuture<ResultType<Function>> then(QtFuture::Launch policy, Function &&function);
0135
0136 template<class Function>
0137 QFuture<ResultType<Function>> then(QThreadPool *pool, Function &&function);
0138
0139 template<class Function>
0140 QFuture<ResultType<Function>> then(QObject *context, Function &&function);
0141
0142 #ifndef QT_NO_EXCEPTIONS
0143 template<class Function,
0144 typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>>
0145 QFuture<T> onFailed(Function &&handler);
0146
0147 template<class Function,
0148 typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>>
0149 QFuture<T> onFailed(QObject *context, Function &&handler);
0150 #endif
0151
0152 template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>>
0153 QFuture<T> onCanceled(Function &&handler);
0154
0155 template<class Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>>
0156 QFuture<T> onCanceled(QObject *context, Function &&handler);
0157
0158 #if !defined(Q_QDOC)
0159 template<class U = T, typename = std::enable_if_t<QtPrivate::isQFutureV<U>>>
0160 auto unwrap();
0161 #else
0162 template<class U>
0163 QFuture<U> unwrap();
0164 #endif
0165
0166 class const_iterator
0167 {
0168 public:
0169 static_assert(!std::is_same_v<T, void>,
0170 "It isn't possible to define QFuture<void>::const_iterator");
0171
0172 typedef std::bidirectional_iterator_tag iterator_category;
0173 typedef qptrdiff difference_type;
0174 typedef T value_type;
0175 typedef const T *pointer;
0176 typedef const T &reference;
0177
0178 inline const_iterator() {}
0179 inline const_iterator(QFuture const * const _future, int _index)
0180 : future(_future), index(advanceIndex(_index, 0)) { }
0181 inline const_iterator(const const_iterator &o) : future(o.future), index(o.index) {}
0182 inline const_iterator &operator=(const const_iterator &o)
0183 { future = o.future; index = o.index; return *this; }
0184 inline const T &operator*() const { return future->d.resultReference(index); }
0185 inline const T *operator->() const { return future->d.resultPointer(index); }
0186 inline const_iterator &operator++()
0187 { index = advanceIndex(index, 1); return *this; }
0188 inline const_iterator &operator--()
0189 { index = advanceIndex(index, -1); return *this; }
0190 inline const_iterator operator++(int)
0191 {
0192 const_iterator r = *this;
0193 index = advanceIndex(index, 1);
0194 return r;
0195 }
0196 inline const_iterator operator--(int)
0197 {
0198 const_iterator r = *this;
0199 index = advanceIndex(index, -1);
0200 return r;
0201 }
0202 inline const_iterator operator+(int j) const
0203 { return const_iterator(future, advanceIndex(index, j)); }
0204 inline const_iterator operator-(int j) const
0205 { return const_iterator(future, advanceIndex(index, -j)); }
0206 inline const_iterator &operator+=(int j)
0207 { index = advanceIndex(index, j); return *this; }
0208 inline const_iterator &operator-=(int j)
0209 { index = advanceIndex(index, -j); return *this; }
0210 friend inline const_iterator operator+(int j, const_iterator k)
0211 { return const_iterator(k.future, k.advanceIndex(k.index, j)); }
0212
0213 private:
0214 friend bool comparesEqual(const const_iterator &lhs, const const_iterator &rhs) noexcept
0215 {
0216 return lhs.index == rhs.index;
0217 }
0218 Q_DECLARE_EQUALITY_COMPARABLE(const_iterator)
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237 int advanceIndex(int idx, int n) const
0238 {
0239
0240 if (idx == -1 && n >= 0)
0241 return idx;
0242
0243
0244
0245 if (idx == -1 && future->isRunning())
0246 future->d.waitForFinished();
0247
0248
0249 const int targetIndex = (idx == -1) ? future->resultCount() + n : idx + n;
0250 future->d.waitForResult(targetIndex);
0251
0252
0253 return (targetIndex < future->resultCount()) ? targetIndex : -1;
0254 }
0255
0256 QFuture const * future;
0257 int index;
0258 };
0259 friend class const_iterator;
0260 typedef const_iterator ConstIterator;
0261
0262 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
0263 const_iterator begin() const { return const_iterator(this, 0); }
0264
0265 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
0266 const_iterator constBegin() const { return const_iterator(this, 0); }
0267
0268 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
0269 const_iterator end() const { return const_iterator(this, -1); }
0270
0271 template<class U = T, typename = QtPrivate::EnableForNonVoid<U>>
0272 const_iterator constEnd() const { return const_iterator(this, -1); }
0273
0274 private:
0275 friend class QFutureWatcher<T>;
0276
0277 template<class U>
0278 friend class QFuture;
0279
0280 friend class QFutureInterfaceBase;
0281
0282 template<class Function, class ResultType, class ParentResultType>
0283 friend class QtPrivate::CompactContinuation;
0284
0285 template<class Function, class ResultType>
0286 friend class QtPrivate::CanceledHandler;
0287
0288 #ifndef QT_NO_EXCEPTIONS
0289 template<class Function, class ResultType>
0290 friend class QtPrivate::FailureHandler;
0291 #endif
0292
0293 template<typename ResultType>
0294 friend struct QtPrivate::WhenAnyContext;
0295
0296 friend struct QtPrivate::UnwrapHandler;
0297
0298 using QFuturePrivate =
0299 std::conditional_t<std::is_same_v<T, void>, QFutureInterfaceBase, QFutureInterface<T>>;
0300
0301 #ifdef QFUTURE_TEST
0302 public:
0303 #endif
0304 mutable QFuturePrivate d;
0305 };
0306
0307 template<typename T>
0308 template<typename U, typename>
0309 inline T QFuture<T>::result() const
0310 {
0311 d.waitForResult(0);
0312 return d.resultReference(0);
0313 }
0314
0315 template<typename T>
0316 template<typename U, typename>
0317 inline T QFuture<T>::resultAt(int index) const
0318 {
0319 d.waitForResult(index);
0320 return d.resultReference(index);
0321 }
0322
0323 template <typename T>
0324 inline QFuture<T> QFutureInterface<T>::future()
0325 {
0326 return QFuture<T>(this);
0327 }
0328
0329 template<class T>
0330 template<class Function>
0331 QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(Function &&function)
0332 {
0333 return then(QtFuture::Launch::Sync, std::forward<Function>(function));
0334 }
0335
0336 template<class T>
0337 template<class Function>
0338 QFuture<typename QFuture<T>::template ResultType<Function>>
0339 QFuture<T>::then(QtFuture::Launch policy, Function &&function)
0340 {
0341 QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
0342 QtPrivate::CompactContinuation<std::decay_t<Function>, ResultType<Function>, T>::create(
0343 std::forward<Function>(function), this, promise, policy);
0344 return promise.future();
0345 }
0346
0347 template<class T>
0348 template<class Function>
0349 QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QThreadPool *pool,
0350 Function &&function)
0351 {
0352 QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
0353 QtPrivate::CompactContinuation<std::decay_t<Function>, ResultType<Function>, T>::create(
0354 std::forward<Function>(function), this, promise, pool);
0355 return promise.future();
0356 }
0357
0358 template<class T>
0359 template<class Function>
0360 QFuture<typename QFuture<T>::template ResultType<Function>> QFuture<T>::then(QObject *context,
0361 Function &&function)
0362 {
0363 QFutureInterface<ResultType<Function>> promise(QFutureInterfaceBase::State::Pending);
0364 QtPrivate::CompactContinuation<std::decay_t<Function>, ResultType<Function>, T>::create(
0365 std::forward<Function>(function), this, promise, context);
0366 return promise.future();
0367 }
0368
0369 #ifndef QT_NO_EXCEPTIONS
0370 template<class T>
0371 template<class Function, typename>
0372 QFuture<T> QFuture<T>::onFailed(Function &&handler)
0373 {
0374 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
0375 QtPrivate::FailureHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
0376 this, promise);
0377 return promise.future();
0378 }
0379
0380 template<class T>
0381 template<class Function, typename>
0382 QFuture<T> QFuture<T>::onFailed(QObject *context, Function &&handler)
0383 {
0384 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
0385 QtPrivate::FailureHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
0386 this, promise, context);
0387 return promise.future();
0388 }
0389
0390 #endif
0391
0392 template<class T>
0393 template<class Function, typename>
0394 QFuture<T> QFuture<T>::onCanceled(Function &&handler)
0395 {
0396 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
0397 QtPrivate::CanceledHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
0398 this, promise);
0399 return promise.future();
0400 }
0401
0402 template<class T>
0403 template<class Function, typename>
0404 QFuture<T> QFuture<T>::onCanceled(QObject *context, Function &&handler)
0405 {
0406 QFutureInterface<T> promise(QFutureInterfaceBase::State::Pending);
0407 QtPrivate::CanceledHandler<std::decay_t<Function>, T>::create(std::forward<Function>(handler),
0408 this, promise, context);
0409 return promise.future();
0410 }
0411
0412 template<class T>
0413 template<class U, typename>
0414 auto QFuture<T>::unwrap()
0415 {
0416 if constexpr (QtPrivate::isQFutureV<typename QtPrivate::Future<T>::type>)
0417 return QtPrivate::UnwrapHandler::unwrapImpl(this).unwrap();
0418 else
0419 return QtPrivate::UnwrapHandler::unwrapImpl(this);
0420 }
0421
0422 inline QFuture<void> QFutureInterface<void>::future()
0423 {
0424 return QFuture<void>(this);
0425 }
0426
0427 template<typename T>
0428 QFutureInterfaceBase QFutureInterfaceBase::get(const QFuture<T> &future)
0429 {
0430 return future.d;
0431 }
0432
0433 namespace QtPrivate
0434 {
0435
0436 template<typename T>
0437 struct MetaTypeQFutureHelper<QFuture<T>>
0438 {
0439 static bool registerConverter() {
0440 if constexpr (std::is_same_v<T, void>) {
0441 return false;
0442 } else {
0443 return QMetaType::registerConverter<QFuture<T>, QFuture<void>>(
0444 [](const QFuture<T> &future) { return QFuture<void>(future); });
0445 }
0446 }
0447 };
0448
0449 }
0450
0451 namespace QtFuture {
0452
0453 #ifndef Q_QDOC
0454
0455 template<typename OutputSequence, typename InputIt,
0456 typename ValueType = typename std::iterator_traits<InputIt>::value_type,
0457 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
0458 QtPrivate::IsRandomAccessible<OutputSequence>,
0459 QtPrivate::isQFuture<ValueType>>,
0460 int> = 0>
0461 QFuture<OutputSequence> whenAll(InputIt first, InputIt last)
0462 {
0463 return QtPrivate::whenAllImpl<OutputSequence, InputIt, ValueType>(first, last);
0464 }
0465
0466 template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
0467 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
0468 QtPrivate::isQFuture<ValueType>>,
0469 int> = 0>
0470 QFuture<QList<ValueType>> whenAll(InputIt first, InputIt last)
0471 {
0472 return QtPrivate::whenAllImpl<QList<ValueType>, InputIt, ValueType>(first, last);
0473 }
0474
0475 template<typename OutputSequence, typename... Futures,
0476 std::enable_if_t<std::conjunction_v<QtPrivate::IsRandomAccessible<OutputSequence>,
0477 QtPrivate::NotEmpty<Futures...>,
0478 QtPrivate::isQFuture<std::decay_t<Futures>>...>,
0479 int> = 0>
0480 QFuture<OutputSequence> whenAll(Futures &&... futures)
0481 {
0482 return QtPrivate::whenAllImpl<OutputSequence, Futures...>(std::forward<Futures>(futures)...);
0483 }
0484
0485 template<typename... Futures,
0486 std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
0487 QtPrivate::isQFuture<std::decay_t<Futures>>...>,
0488 int> = 0>
0489 QFuture<QList<std::variant<std::decay_t<Futures>...>>> whenAll(Futures &&... futures)
0490 {
0491 return QtPrivate::whenAllImpl<QList<std::variant<std::decay_t<Futures>...>>, Futures...>(
0492 std::forward<Futures>(futures)...);
0493 }
0494
0495 template<typename InputIt, typename ValueType = typename std::iterator_traits<InputIt>::value_type,
0496 std::enable_if_t<std::conjunction_v<QtPrivate::IsForwardIterable<InputIt>,
0497 QtPrivate::isQFuture<ValueType>>,
0498 int> = 0>
0499 QFuture<WhenAnyResult<typename QtPrivate::Future<ValueType>::type>> whenAny(InputIt first,
0500 InputIt last)
0501 {
0502 return QtPrivate::whenAnyImpl<InputIt, ValueType>(first, last);
0503 }
0504
0505 template<typename... Futures,
0506 std::enable_if_t<std::conjunction_v<QtPrivate::NotEmpty<Futures...>,
0507 QtPrivate::isQFuture<std::decay_t<Futures>>...>,
0508 int> = 0>
0509 QFuture<std::variant<std::decay_t<Futures>...>> whenAny(Futures &&... futures)
0510 {
0511 return QtPrivate::whenAnyImpl(std::forward<Futures>(futures)...);
0512 }
0513
0514 #else
0515
0516 template<typename OutputSequence, typename InputIt>
0517 QFuture<OutputSequence> whenAll(InputIt first, InputIt last);
0518
0519 template<typename OutputSequence, typename... Futures>
0520 QFuture<OutputSequence> whenAll(Futures &&... futures);
0521
0522 template<typename T, typename InputIt>
0523 QFuture<QtFuture::WhenAnyResult<T>> whenAny(InputIt first, InputIt last);
0524
0525 template<typename... Futures>
0526 QFuture<std::variant<std::decay_t<Futures>...>> whenAny(Futures &&... futures);
0527
0528 #endif
0529
0530 #if QT_DEPRECATED_SINCE(6, 10)
0531 #if defined(Q_QDOC)
0532 static QFuture<void> makeReadyFuture()
0533 #else
0534 template<typename T = void>
0535 QT_DEPRECATED_VERSION_X(6, 10, "Use makeReadyVoidFuture() instead.")
0536 static QFuture<T> makeReadyFuture()
0537 #endif
0538 {
0539 return makeReadyVoidFuture();
0540 }
0541 #endif
0542
0543 }
0544
0545 Q_DECLARE_SEQUENTIAL_ITERATOR(Future)
0546
0547 QT_END_NAMESPACE
0548
0549 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QFuture)
0550
0551 #endif