1
0

future 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. #pragma once
  2. #if __cplusplus < 201103L
  3. #error "C++ version lower than C++11"
  4. #endif
  5. #include <mutex>
  6. #include <condition_variable>
  7. #include <memory>
  8. #include <chrono>
  9. #include <cassert>
  10. namespace std {
  11. enum class future_status {
  12. ready,
  13. timeout,
  14. deferred
  15. };
  16. namespace detail {
  17. class shared_state_base {
  18. protected:
  19. typedef void (*deleter_fn)(void *v);
  20. using scoped_lock = std::lock_guard<std::mutex>;
  21. using unique_lock = std::unique_lock<std::mutex>;
  22. public:
  23. explicit shared_state_base(deleter_fn d) : v_(nullptr), d_(d), valid_(true) {}
  24. ~shared_state_base() { d_(v_); }
  25. shared_state_base(shared_state_base &&other) = delete;
  26. shared_state_base(const shared_state_base &other) = delete;
  27. shared_state_base &operator=(shared_state_base &&other) = delete;
  28. shared_state_base &operator=(const shared_state_base &other) = delete;
  29. void wait() {
  30. unique_lock lock(m_);
  31. c_.wait(lock, [this] { return has_value(); });
  32. }
  33. template <class Rep, class Period>
  34. std::future_status
  35. wait_for(const std::chrono::duration<Rep, Period> &rel_time) {
  36. unique_lock lock(m_);
  37. if (c_.wait_for(lock, rel_time, [this] { return has_value(); })) {
  38. return std::future_status::ready;
  39. }
  40. return std::future_status::timeout;
  41. }
  42. template <class Clock, class Duration>
  43. std::future_status
  44. wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) {
  45. unique_lock lock(m_);
  46. if (c_.wait_until(lock, abs_time, [this] { return has_value(); })) {
  47. return std::future_status::ready;
  48. }
  49. return std::future_status::timeout;
  50. }
  51. protected:
  52. bool has_value() { return v_ != nullptr; }
  53. protected:
  54. std::mutex m_;
  55. std::condition_variable c_;
  56. void *v_;
  57. deleter_fn d_;
  58. bool valid_;
  59. };
  60. template <typename R>
  61. class shared_state: public shared_state_base {
  62. public:
  63. shared_state() :shared_state_base(default_deleter_) {}
  64. ~shared_state() {}
  65. R &get() {
  66. wait();
  67. scoped_lock lock(m_);
  68. assert(valid_);
  69. valid_ = false;
  70. return *(static_cast<R *>(v_));
  71. }
  72. void set(const R &v) {
  73. scoped_lock lock(m_);
  74. assert(!has_value());
  75. v_ = new R(v);
  76. valid_ = true;
  77. c_.notify_one();
  78. }
  79. void set(R &&v) {
  80. scoped_lock lock(m_);
  81. assert(!has_value());
  82. v_ = new R(std::move(v));
  83. valid_ = true;
  84. c_.notify_one();
  85. }
  86. bool valid() {
  87. scoped_lock lock(m_);
  88. return valid_;
  89. }
  90. private:
  91. static void default_deleter_(void *v) { delete static_cast<R *>(v); }
  92. };
  93. } // namespace detail
  94. template <typename R>
  95. class shared_future {
  96. };
  97. template <typename R>
  98. class future {
  99. using state_type = std::shared_ptr<detail::shared_state<R>>;
  100. public:
  101. future() {}
  102. explicit future(const state_type &state) : state_(state) {}
  103. future(future &&other) noexcept: state_(std::move(other.state_)) {
  104. other.state_.reset();
  105. }
  106. future(const future &other) = delete;
  107. ~future() {}
  108. future &operator=(future &&other) noexcept {
  109. if (&other != this) {
  110. state_ = std::move(other.state_);
  111. other.state_.reset();
  112. }
  113. return *this;
  114. }
  115. future &operator=(const future &other) = delete;
  116. void swap(future &other) noexcept {
  117. std::swap(state_, other.state_);
  118. }
  119. std::shared_future<R> share() noexcept { return std::shared_future<R>(); }
  120. R get() { return state_->get(); }
  121. bool valid() const noexcept { return state_->valid(); }
  122. void wait() const { state_->wait(); }
  123. template <class Rep, class Period>
  124. std::future_status
  125. wait_for(const std::chrono::duration<Rep, Period> &rel_time) const {
  126. return state_->wait_for(rel_time);
  127. }
  128. template <class Clock, class Duration>
  129. std::future_status
  130. wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) const {
  131. return state_->wait_until(abs_time);
  132. }
  133. private:
  134. state_type state_;
  135. };
  136. template <>
  137. class future<void> {
  138. using state_type = std::shared_ptr<detail::shared_state<int>>;
  139. public:
  140. future() {}
  141. explicit future(const state_type &state) : state_(state) {}
  142. future(future &&other) noexcept: state_(std::move(other.state_)) {
  143. other.state_.reset();
  144. }
  145. future(const future &other) = delete;
  146. ~future() {}
  147. future &operator=(future &&other) noexcept {
  148. if (&other != this) {
  149. state_ = std::move(other.state_);
  150. other.state_.reset();
  151. }
  152. return *this;
  153. }
  154. future &operator=(const future &other) = delete;
  155. void swap(future &other) noexcept {
  156. std::swap(state_, other.state_);
  157. }
  158. std::shared_future<void> share() noexcept { return std::shared_future<void>(); }
  159. void get() { state_->get(); }
  160. bool valid() const noexcept { return state_->valid(); }
  161. void wait() const { state_->wait(); }
  162. template <class Rep, class Period>
  163. std::future_status
  164. wait_for(const std::chrono::duration<Rep, Period> &rel_time) const {
  165. return state_->wait_for(rel_time);
  166. }
  167. template <class Clock, class Duration>
  168. std::future_status
  169. wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) const {
  170. return state_->wait_until(abs_time);
  171. }
  172. private:
  173. state_type state_;
  174. };
  175. template <typename R>
  176. class promise {
  177. using state_type = std::shared_ptr<detail::shared_state<R>>;
  178. public:
  179. promise() : state_(new detail::shared_state<R>()) {}
  180. promise(promise &&other) noexcept: state_(std::move(other.state_)) {
  181. other.state_.reset();
  182. }
  183. promise(const promise &other) = delete;
  184. ~promise() {}
  185. promise &operator=(promise &&other) noexcept {
  186. if (&other != this) {
  187. state_ = std::move(other.state_);
  188. other.state_.reset();
  189. }
  190. return *this;
  191. }
  192. promise &operator=(const promise &other) = delete;
  193. void swap(promise &other) noexcept {
  194. std::swap(state_, other.state_);
  195. }
  196. std::future<R> get_future() { return std::future<R>(state_); }
  197. void set_value(const R &value) { state_->set(value); }
  198. void set_value(R &&value) { state_->set(std::move(value)); }
  199. void set_value_at_thread_exit(const R &value);
  200. void set_value_at_thread_exit(R &&value);
  201. void set_exception(std::exception_ptr p);
  202. void set_exception_at_thread_exit(std::exception_ptr p);
  203. private:
  204. state_type state_;
  205. };
  206. template <>
  207. class promise<void> {
  208. using state_type = std::shared_ptr<detail::shared_state<int>>;
  209. public:
  210. promise() : state_(new detail::shared_state<int>()) {}
  211. promise(promise &&other) noexcept: state_(std::move(other.state_)) {
  212. other.state_.reset();
  213. }
  214. promise(const promise &other) = delete;
  215. ~promise() {}
  216. promise &operator=(promise &&other) noexcept {
  217. if (&other != this) {
  218. state_ = std::move(other.state_);
  219. other.state_.reset();
  220. }
  221. return *this;
  222. }
  223. promise &operator=(const promise &other) = delete;
  224. void swap(promise &other) noexcept {
  225. std::swap(state_, other.state_);
  226. }
  227. std::future<void> get_future() { return std::future<void>(state_); }
  228. void set_value() { state_->set(0); }
  229. void set_value_at_thread_exit();
  230. void set_exception(std::exception_ptr p);
  231. void set_exception_at_thread_exit(std::exception_ptr p);
  232. private:
  233. state_type state_;
  234. };
  235. template <class R>
  236. void swap(std::future<R> &lhs, std::future<R> &rhs) noexcept {
  237. lhs.swap(rhs);
  238. }
  239. template <class R>
  240. void swap(std::promise<R> &lhs, std::promise<R> &rhs) noexcept {
  241. lhs.swap(rhs);
  242. }
  243. } // namespace std