Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-11 09:22:08

0001 // Copyright (C) 2020 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 QPROMISE_H
0006 #define QPROMISE_H
0007 
0008 #include <QtCore/qglobal.h>
0009 #include <QtCore/qfutureinterface.h>
0010 
0011 #include <utility>
0012 
0013 QT_REQUIRE_CONFIG(future);
0014 
0015 QT_BEGIN_NAMESPACE
0016 
0017 namespace QtPrivate {
0018 
0019 template<class T, class U>
0020 using EnableIfSameOrConvertible = std::enable_if_t<std::is_convertible_v<T, U>>;
0021 
0022 } // namespace QtPrivate
0023 
0024 template<typename T>
0025 class QPromise
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     QPromise() = default;
0032     Q_DISABLE_COPY(QPromise)
0033     QPromise(QPromise<T> &&other) = default;
0034     QPromise(const QFutureInterface<T> &other) : d(other) {}
0035     QPromise(QFutureInterface<T> &&other) noexcept : d(std::move(other)) {}
0036     QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QPromise)
0037     ~QPromise()
0038     {
0039         // If computation is not finished at this point, cancel
0040         // potential waits
0041         if (d.d && !(d.loadState() & QFutureInterfaceBase::State::Finished)) {
0042             d.cancelAndFinish(); // cancel and finalize the state
0043             d.runContinuation();
0044         }
0045         d.cleanContinuation();
0046     }
0047 
0048     // Core QPromise APIs
0049     QFuture<T> future() const { return d.future(); }
0050     template<typename...Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true>
0051     bool emplaceResultAt(int index, Args&&...args)
0052     {
0053         return d.reportAndEmplaceResult(index, std::forward<Args>(args)...);
0054     }
0055     template<typename...Args, std::enable_if_t<std::is_constructible_v<T, Args...>, bool> = true>
0056     bool emplaceResult(Args&&...args)
0057     {
0058         return d.reportAndEmplaceResult(-1, std::forward<Args>(args)...);
0059     }
0060     template<typename U = T, typename = QtPrivate::EnableIfSameOrConvertible<U, T>>
0061     bool addResult(U &&result, int index = -1)
0062     {
0063         return d.reportAndEmplaceResult(index, std::forward<U>(result));
0064     }
0065     bool addResults(const QList<T> &result)
0066     { return d.reportResults(result); }
0067 #ifndef QT_NO_EXCEPTIONS
0068     void setException(const QException &e) { d.reportException(e); }
0069 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
0070     void setException(std::exception_ptr e) { d.reportException(e); }
0071 #else
0072     void setException(const std::exception_ptr &e) { d.reportException(e); }
0073 #endif
0074 #endif
0075     void start() { d.reportStarted(); }
0076     void finish() { d.reportFinished(); }
0077 
0078     void suspendIfRequested() { d.suspendIfRequested(); }
0079 
0080     bool isCanceled() const { return d.isCanceled(); }
0081 
0082     // Progress methods
0083     void setProgressRange(int minimum, int maximum) { d.setProgressRange(minimum, maximum); }
0084     void setProgressValue(int progressValue) { d.setProgressValue(progressValue); }
0085     void setProgressValueAndText(int progressValue, const QString &progressText)
0086     {
0087         d.setProgressValueAndText(progressValue, progressText);
0088     }
0089 
0090     void swap(QPromise<T> &other) noexcept
0091     {
0092         d.swap(other.d);
0093     }
0094 
0095 #if defined(Q_QDOC)  // documentation-only simplified signatures
0096     bool addResult(const T &result, int index = -1) { }
0097     bool addResult(T &&result, int index = -1) { }
0098 #endif
0099 private:
0100     mutable QFutureInterface<T> d;
0101 };
0102 
0103 template<typename T>
0104 inline void swap(QPromise<T> &a, QPromise<T> &b) noexcept
0105 {
0106     a.swap(b);
0107 }
0108 
0109 QT_END_NAMESPACE
0110 
0111 #endif  // QPROMISE_H