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