File indexing completed on 2026-09-11 09:22:08
0001
0002
0003
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 }
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
0040
0041 if (d.d && !(d.loadState() & QFutureInterfaceBase::State::Finished)) {
0042 d.cancelAndFinish();
0043 d.runContinuation();
0044 }
0045 d.cleanContinuation();
0046 }
0047
0048
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
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)
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