| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- #ifndef QPROMISE_H
- #define QPROMISE_H
- #include <QtCore/QException>
- #include <QtCore/QFutureInterface>
- #include <QtCore/QGlobal.h>
- #include <type_traits>
- #include <utility>
- QT_BEGIN_NAMESPACE
- namespace QtPrivate {
- template<class T, class U>
- struct EnableIfSameOrConvertible
- {
- typedef typename std::enable_if<std::is_convertible<T, U>::value>::type type;
- };
- } // namespace QtPrivate
- template<typename T>
- class QPromise
- {
- static_assert(std::is_move_constructible<T>::value || std::is_same<T, void>::value,
- "A move-constructible type or type void is required");
- public:
- QPromise() = default;
- Q_DISABLE_COPY(QPromise)
- QPromise(QPromise<T> &&other) Q_DECL_NOEXCEPT : d(std::move(other.d)) {}
- QPromise(const QFutureInterface<T> &other)
- : d(other)
- {}
- QPromise(QFutureInterface<T> &&other) Q_DECL_NOEXCEPT : d(std::move(other)) {}
- QPromise &operator=(QPromise<T> &&other) Q_DECL_NOEXCEPT
- {
- swap(other);
- return *this;
- }
- ~QPromise()
- {
- const bool wasFinished = d.queryState(QFutureInterfaceBase::Finished);
- if (!wasFinished) {
- d.cancel(); // Qt5需单独取消
- d.reportFinished(); // 显式标记完成
- }
- // if (d.isValid() && !d.queryState(QFutureInterfaceBase::Finished)) {
- // d.cancel();
- // d.reportFinished();
- // d.runContinuations();
- // }
- // d.clearContinuations();
- }
- // Core API
- QFuture<T> future() const { return const_cast<QFutureInterface<T> &>(d).future(); }
- template<typename... Args>
- typename std::enable_if<std::is_constructible<T, Args...>::value, bool>::type emplaceResultAt(
- int index, Args &&...args)
- {
- return d.reportResult(index, T(std::forward<Args>(args)...));
- }
- template<typename... Args>
- typename std::enable_if<std::is_constructible<T, Args...>::value, bool>::type emplaceResult(
- Args &&...args)
- {
- return d.reportResult(T(std::forward<Args>(args)...));
- }
- template<typename U = T>
- typename QtPrivate::EnableIfSameOrConvertible<U, T>::type addResult(U &&result, int index = -1)
- {
- return d.reportResult(std::forward<U>(result), index);
- }
- bool addResults(const QList<T> &results)
- {
- foreach (const T &result, results)
- if (!d.reportResult(result))
- return false;
- return true;
- }
- #ifndef QT_NO_EXCEPTIONS
- void setException(const QException &e) { d.reportException(e); }
- void setException(std::exception_ptr e)
- {
- try {
- std::rethrow_exception(e);
- } catch (...) {
- d.reportException(std::current_exception());
- }
- }
- #endif
- void start() { d.reportStarted(); }
- void finish() { d.reportFinished(); }
- void suspendIfRequested()
- {
- if (d.isSuspended())
- d.waitForResume();
- }
- bool isCanceled() const { return const_cast<QFutureInterface<T> &>(d).isCanceled(); }
- // Progress
- void setProgressRange(int min, int max) { d.setProgressRange(min, max); }
- void setProgressValue(int val) { d.setProgressValue(val); }
- void setProgressValueAndText(int val, const QString &text)
- {
- d.setProgressValueAndText(val, text);
- }
- void swap(QPromise<T> &other) Q_DECL_NOEXCEPT { qSwap(d, other.d); }
- private:
- mutable QFutureInterface<T> d;
- };
- template<typename T>
- inline void swap(QPromise<T> &a, QPromise<T> &b) Q_DECL_NOEXCEPT
- {
- a.swap(b);
- }
- QT_END_NAMESPACE
- #endif // QPROMISE_H
|