summaryrefslogtreecommitdiff
path: root/components/cplusplus/cpp11/gcc/future
diff options
context:
space:
mode:
authorliukangcc <[email protected]>2021-09-03 11:38:48 +0800
committerliukangcc <[email protected]>2021-09-16 09:51:33 +0800
commita3541b2a243bdf1cc49029b696b217ce752199c7 (patch)
treeed7bd0398a322fb597938f3fb476909a7cc66606 /components/cplusplus/cpp11/gcc/future
parentdca7dcb42a44249abbe6c36ce2a69355e60d1f79 (diff)
[update] support armclang and c++11.
Diffstat (limited to 'components/cplusplus/cpp11/gcc/future')
-rw-r--r--components/cplusplus/cpp11/gcc/future336
1 files changed, 336 insertions, 0 deletions
diff --git a/components/cplusplus/cpp11/gcc/future b/components/cplusplus/cpp11/gcc/future
new file mode 100644
index 0000000000..6a686063fb
--- /dev/null
+++ b/components/cplusplus/cpp11/gcc/future
@@ -0,0 +1,336 @@
+#pragma once
+
+#if __cplusplus < 201103L
+#error "C++ version lower than C++11"
+#endif
+
+#include <mutex>
+#include <condition_variable>
+#include <memory>
+#include <chrono>
+#include <cassert>
+
+namespace std {
+
+enum class future_status {
+ ready,
+ timeout,
+ deferred
+};
+
+namespace detail {
+
+class shared_state_base {
+protected:
+ typedef void (*deleter_fn)(void *v);
+
+ using scoped_lock = std::lock_guard<std::mutex>;
+ using unique_lock = std::unique_lock<std::mutex>;
+public:
+ explicit shared_state_base(deleter_fn d) : v_(nullptr), d_(d), valid_(true) {}
+
+ ~shared_state_base() { d_(v_); }
+
+ shared_state_base(shared_state_base &&other) = delete;
+
+ shared_state_base(const shared_state_base &other) = delete;
+
+ shared_state_base &operator=(shared_state_base &&other) = delete;
+
+ shared_state_base &operator=(const shared_state_base &other) = delete;
+
+ void wait() {
+ unique_lock lock(m_);
+ c_.wait(lock, [this] { return has_value(); });
+ }
+
+ template <class Rep, class Period>
+ std::future_status
+ wait_for(const std::chrono::duration<Rep, Period> &rel_time) {
+ unique_lock lock(m_);
+ if (c_.wait_for(lock, rel_time, [this] { return has_value(); })) {
+ return std::future_status::ready;
+ }
+ return std::future_status::timeout;
+ }
+
+ template <class Clock, class Duration>
+ std::future_status
+ wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) {
+ unique_lock lock(m_);
+ if (c_.wait_until(lock, abs_time, [this] { return has_value(); })) {
+ return std::future_status::ready;
+ }
+ return std::future_status::timeout;
+ }
+
+protected:
+ bool has_value() { return v_ != nullptr; }
+
+protected:
+ std::mutex m_;
+ std::condition_variable c_;
+ void *v_;
+ deleter_fn d_;
+ bool valid_;
+};
+
+
+template <typename R>
+class shared_state: public shared_state_base {
+public:
+ shared_state() :shared_state_base(default_deleter_) {}
+
+ ~shared_state() {}
+
+ R &get() {
+ wait();
+ scoped_lock lock(m_);
+ assert(valid_);
+ valid_ = false;
+ return *(static_cast<R *>(v_));
+ }
+
+ void set(const R &v) {
+ scoped_lock lock(m_);
+ assert(!has_value());
+ v_ = new R(v);
+ valid_ = true;
+ c_.notify_one();
+ }
+
+ void set(R &&v) {
+ scoped_lock lock(m_);
+ assert(!has_value());
+ v_ = new R(std::move(v));
+ valid_ = true;
+ c_.notify_one();
+ }
+
+ bool valid() {
+ scoped_lock lock(m_);
+ return valid_;
+ }
+
+private:
+ static void default_deleter_(void *v) { delete static_cast<R *>(v); }
+};
+
+} // namespace detail
+
+template <typename R>
+class shared_future {
+};
+
+
+template <typename R>
+class future {
+ using state_type = std::shared_ptr<detail::shared_state<R>>;
+public:
+ future() {}
+
+ explicit future(const state_type &state) : state_(state) {}
+
+ future(future &&other) noexcept: state_(std::move(other.state_)) {
+ other.state_.reset();
+ }
+
+ future(const future &other) = delete;
+
+ ~future() {}
+
+ future &operator=(future &&other) noexcept {
+ if (&other != this) {
+ state_ = std::move(other.state_);
+ other.state_.reset();
+ }
+ return *this;
+ }
+
+ future &operator=(const future &other) = delete;
+
+ void swap(future &other) noexcept {
+ std::swap(state_, other.state_);
+ }
+
+ std::shared_future<R> share() noexcept { return std::shared_future<R>(); }
+
+ R get() { return state_->get(); }
+
+ bool valid() const noexcept { return state_->valid(); }
+
+ void wait() const { state_->wait(); }
+
+ template <class Rep, class Period>
+ std::future_status
+ wait_for(const std::chrono::duration<Rep, Period> &rel_time) const {
+ return state_->wait_for(rel_time);
+ }
+
+ template <class Clock, class Duration>
+ std::future_status
+ wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) const {
+ return state_->wait_until(abs_time);
+ }
+
+private:
+ state_type state_;
+};
+
+
+template <>
+class future<void> {
+ using state_type = std::shared_ptr<detail::shared_state<int>>;
+public:
+ future() {}
+
+ explicit future(const state_type &state) : state_(state) {}
+
+ future(future &&other) noexcept: state_(std::move(other.state_)) {
+ other.state_.reset();
+ }
+
+ future(const future &other) = delete;
+
+ ~future() {}
+
+ future &operator=(future &&other) noexcept {
+ if (&other != this) {
+ state_ = std::move(other.state_);
+ other.state_.reset();
+ }
+ return *this;
+ }
+
+ future &operator=(const future &other) = delete;
+
+ void swap(future &other) noexcept {
+ std::swap(state_, other.state_);
+ }
+
+ std::shared_future<void> share() noexcept { return std::shared_future<void>(); }
+
+ void get() { state_->get(); }
+
+ bool valid() const noexcept { return state_->valid(); }
+
+ void wait() const { state_->wait(); }
+
+ template <class Rep, class Period>
+ std::future_status
+ wait_for(const std::chrono::duration<Rep, Period> &rel_time) const {
+ return state_->wait_for(rel_time);
+ }
+
+ template <class Clock, class Duration>
+ std::future_status
+ wait_until(const std::chrono::time_point<Clock, Duration> &abs_time) const {
+ return state_->wait_until(abs_time);
+ }
+
+private:
+ state_type state_;
+};
+
+
+template <typename R>
+class promise {
+ using state_type = std::shared_ptr<detail::shared_state<R>>;
+public:
+ promise() : state_(new detail::shared_state<R>()) {}
+
+ promise(promise &&other) noexcept: state_(std::move(other.state_)) {
+ other.state_.reset();
+ }
+
+ promise(const promise &other) = delete;
+
+ ~promise() {}
+
+ promise &operator=(promise &&other) noexcept {
+ if (&other != this) {
+ state_ = std::move(other.state_);
+ other.state_.reset();
+ }
+ return *this;
+ }
+
+ promise &operator=(const promise &other) = delete;
+
+ void swap(promise &other) noexcept {
+ std::swap(state_, other.state_);
+ }
+
+ std::future<R> get_future() { return std::future<R>(state_); }
+
+ void set_value(const R &value) { state_->set(value); }
+
+ void set_value(R &&value) { state_->set(std::move(value)); }
+
+ void set_value_at_thread_exit(const R &value);
+
+ void set_value_at_thread_exit(R &&value);
+
+ void set_exception(std::exception_ptr p);
+
+ void set_exception_at_thread_exit(std::exception_ptr p);
+
+private:
+ state_type state_;
+};
+
+
+template <>
+class promise<void> {
+ using state_type = std::shared_ptr<detail::shared_state<int>>;
+public:
+ promise() : state_(new detail::shared_state<int>()) {}
+
+ promise(promise &&other) noexcept: state_(std::move(other.state_)) {
+ other.state_.reset();
+ }
+
+ promise(const promise &other) = delete;
+
+ ~promise() {}
+
+ promise &operator=(promise &&other) noexcept {
+ if (&other != this) {
+ state_ = std::move(other.state_);
+ other.state_.reset();
+ }
+ return *this;
+ }
+
+ promise &operator=(const promise &other) = delete;
+
+ void swap(promise &other) noexcept {
+ std::swap(state_, other.state_);
+ }
+
+ std::future<void> get_future() { return std::future<void>(state_); }
+
+ void set_value() { state_->set(0); }
+
+ void set_value_at_thread_exit();
+
+ void set_exception(std::exception_ptr p);
+
+ void set_exception_at_thread_exit(std::exception_ptr p);
+
+private:
+ state_type state_;
+};
+
+
+template <class R>
+void swap(std::future<R> &lhs, std::future<R> &rhs) noexcept {
+ lhs.swap(rhs);
+}
+
+template <class R>
+void swap(std::promise<R> &lhs, std::promise<R> &rhs) noexcept {
+ lhs.swap(rhs);
+}
+
+} // namespace std