qpromise.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #ifndef QPROMISE_H
  2. #define QPROMISE_H
  3. #include <QtCore/QException>
  4. #include <QtCore/QFutureInterface>
  5. #include <QtCore/QGlobal.h>
  6. #include <type_traits>
  7. #include <utility>
  8. QT_BEGIN_NAMESPACE
  9. namespace QtPrivate {
  10. template<class T, class U>
  11. struct EnableIfSameOrConvertible
  12. {
  13. typedef typename std::enable_if<std::is_convertible<T, U>::value>::type type;
  14. };
  15. } // namespace QtPrivate
  16. template<typename T>
  17. class QPromise
  18. {
  19. static_assert(std::is_move_constructible<T>::value || std::is_same<T, void>::value,
  20. "A move-constructible type or type void is required");
  21. public:
  22. QPromise() = default;
  23. Q_DISABLE_COPY(QPromise)
  24. QPromise(QPromise<T> &&other) Q_DECL_NOEXCEPT : d(std::move(other.d)) {}
  25. QPromise(const QFutureInterface<T> &other)
  26. : d(other)
  27. {}
  28. QPromise(QFutureInterface<T> &&other) Q_DECL_NOEXCEPT : d(std::move(other)) {}
  29. QPromise &operator=(QPromise<T> &&other) Q_DECL_NOEXCEPT
  30. {
  31. swap(other);
  32. return *this;
  33. }
  34. ~QPromise()
  35. {
  36. const bool wasFinished = d.queryState(QFutureInterfaceBase::Finished);
  37. if (!wasFinished) {
  38. d.cancel(); // Qt5需单独取消
  39. d.reportFinished(); // 显式标记完成
  40. }
  41. // if (d.isValid() && !d.queryState(QFutureInterfaceBase::Finished)) {
  42. // d.cancel();
  43. // d.reportFinished();
  44. // d.runContinuations();
  45. // }
  46. // d.clearContinuations();
  47. }
  48. // Core API
  49. QFuture<T> future() const { return const_cast<QFutureInterface<T> &>(d).future(); }
  50. template<typename... Args>
  51. typename std::enable_if<std::is_constructible<T, Args...>::value, bool>::type emplaceResultAt(
  52. int index, Args &&...args)
  53. {
  54. return d.reportResult(index, T(std::forward<Args>(args)...));
  55. }
  56. template<typename... Args>
  57. typename std::enable_if<std::is_constructible<T, Args...>::value, bool>::type emplaceResult(
  58. Args &&...args)
  59. {
  60. return d.reportResult(T(std::forward<Args>(args)...));
  61. }
  62. template<typename U = T>
  63. typename QtPrivate::EnableIfSameOrConvertible<U, T>::type addResult(U &&result, int index = -1)
  64. {
  65. return d.reportResult(std::forward<U>(result), index);
  66. }
  67. bool addResults(const QList<T> &results)
  68. {
  69. foreach (const T &result, results)
  70. if (!d.reportResult(result))
  71. return false;
  72. return true;
  73. }
  74. #ifndef QT_NO_EXCEPTIONS
  75. void setException(const QException &e) { d.reportException(e); }
  76. void setException(std::exception_ptr e)
  77. {
  78. try {
  79. std::rethrow_exception(e);
  80. } catch (...) {
  81. d.reportException(std::current_exception());
  82. }
  83. }
  84. #endif
  85. void start() { d.reportStarted(); }
  86. void finish() { d.reportFinished(); }
  87. void suspendIfRequested()
  88. {
  89. if (d.isSuspended())
  90. d.waitForResume();
  91. }
  92. bool isCanceled() const { return const_cast<QFutureInterface<T> &>(d).isCanceled(); }
  93. // Progress
  94. void setProgressRange(int min, int max) { d.setProgressRange(min, max); }
  95. void setProgressValue(int val) { d.setProgressValue(val); }
  96. void setProgressValueAndText(int val, const QString &text)
  97. {
  98. d.setProgressValueAndText(val, text);
  99. }
  100. void swap(QPromise<T> &other) Q_DECL_NOEXCEPT { qSwap(d, other.d); }
  101. private:
  102. mutable QFutureInterface<T> d;
  103. };
  104. template<typename T>
  105. inline void swap(QPromise<T> &a, QPromise<T> &b) Q_DECL_NOEXCEPT
  106. {
  107. a.swap(b);
  108. }
  109. QT_END_NAMESPACE
  110. #endif // QPROMISE_H