| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 | #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 detailtemplate <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
 |