Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-02 08:14:28

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:significant reason:default
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) // internal
0038         : d(*p)
0039     { }
0040 
0041     template<typename U = T, typename = QtPrivate::EnableForVoid<U>>
0042     explicit QFuture(QFutureInterfaceBase *p) // internal
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     // TODO: Enable and make it return a QList, when QList is fixed to support move-only types
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         /*! \internal
0223 
0224             Advances the iterator index \a idx \a n steps, waits for the
0225             result at the target index, and returns the target index.
0226 
0227             The index may be -1, indicating the end iterator, either
0228             as the argument or as the return value. The end iterator
0229             may be decremented.
0230 
0231             The caller is responsible for not advancing the iterator
0232             before begin() or past end(), with the exception that
0233             attempting to advance a non-end iterator past end() for
0234             a running future is allowed and will return the end iterator.
0235 
0236             Note that n == 0 is valid and will wait for the result
0237             at the given index.
0238         */
0239         int advanceIndex(int idx, int n) const
0240         {
0241             // The end iterator can be decremented, leave as-is for other cases
0242             if (idx == -1 && n >= 0)
0243                 return idx;
0244 
0245             // Special case for decrementing the end iterator: wait for
0246             // finished to get the total result count.
0247             if (idx == -1 && future->isRunning())
0248                 future->d.waitForFinished();
0249 
0250             // Wait for result at target index
0251             const int targetIndex = (idx == -1) ? future->resultCount() + n : idx + n;
0252             future->d.waitForResult(targetIndex);
0253 
0254             // After waiting there is either a result or the end was reached
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 }  // namespace QtPrivate
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 // Q_QDOC
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 // QT_DEPRECATED_SINCE(6, 10)
0544 
0545 } // namespace QtFuture
0546 
0547 Q_DECLARE_SEQUENTIAL_ITERATOR(Future)
0548 
0549 QT_END_NAMESPACE
0550 
0551 Q_DECLARE_METATYPE_TEMPLATE_1ARG(QFuture)
0552 
0553 #endif // QFUTURE_H