#ifndef QPROMISE_H #define QPROMISE_H #include #include #include #include #include QT_BEGIN_NAMESPACE namespace QtPrivate { template struct EnableIfSameOrConvertible { typedef typename std::enable_if::value>::type type; }; } // namespace QtPrivate template class QPromise { static_assert(std::is_move_constructible::value || std::is_same::value, "A move-constructible type or type void is required"); public: QPromise() = default; Q_DISABLE_COPY(QPromise) QPromise(QPromise &&other) Q_DECL_NOEXCEPT : d(std::move(other.d)) {} QPromise(const QFutureInterface &other) : d(other) {} QPromise(QFutureInterface &&other) Q_DECL_NOEXCEPT : d(std::move(other)) {} QPromise &operator=(QPromise &&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 future() const { return const_cast &>(d).future(); } template typename std::enable_if::value, bool>::type emplaceResultAt( int index, Args &&...args) { return d.reportResult(index, T(std::forward(args)...)); } template typename std::enable_if::value, bool>::type emplaceResult( Args &&...args) { return d.reportResult(T(std::forward(args)...)); } template typename QtPrivate::EnableIfSameOrConvertible::type addResult(U &&result, int index = -1) { return d.reportResult(std::forward(result), index); } bool addResults(const QList &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 &>(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 &other) Q_DECL_NOEXCEPT { qSwap(d, other.d); } private: mutable QFutureInterface d; }; template inline void swap(QPromise &a, QPromise &b) Q_DECL_NOEXCEPT { a.swap(b); } QT_END_NAMESPACE #endif // QPROMISE_H