31 #include <boost/fiber/future.hpp>
32 #include <condition_variable>
35 #include <type_traits>
42 template <
typename R,
typename MutexType,
typename ConditionVariableType>
47 if (contains_value_) {
54 template <
typename Argument>
55 void set(Argument&& argument) {
57 std::scoped_lock lock(mutex_);
58 if (contains_value_) {
59 throw std::future_error(std::future_errc::promise_already_satisfied);
62 new (&value_storage_) R(std::forward<Argument>(argument));
63 contains_value_ =
true;
65 condition_variable_.notify_all();
70 std::unique_lock lock(mutex_);
71 if (contains_value_) {
74 contains_value_ =
false;
79 void wait() const noexcept {
80 std::unique_lock lock(mutex_);
86 std::unique_lock lock(mutex_);
88 contains_value_ =
false;
89 return std::move(*
reinterpret_cast<R*
>(&value_storage_));
94 std::scoped_lock lock(mutex_);
95 return contains_value_;
100 std::aligned_storage_t<
sizeof(R), std::alignment_of_v<R>> value_storage_;
103 bool contains_value_;
106 mutable MutexType mutex_;
107 mutable ConditionVariableType condition_variable_;
110 void wait_helper(std::unique_lock<decltype(mutex_)>& lock)
const noexcept {
111 if (!contains_value_) {
112 condition_variable_.wait(lock, [
this] {
return contains_value_; });
117 void delete_helper() noexcept {
reinterpret_cast<R*
>(&value_storage_)->~R(); }
122 template <
typename R,
typename MutexType,
typename ConditionVariableType>
127 template <
typename R,
typename MutexType = std::mutex,
128 typename ConditionVariableType = std::condition_variable>
139 other.shared_state_ =
nullptr;
149 shared_state_ = std::move(other.shared_state_);
150 other.shared_state_ =
nullptr;
156 if (!shared_state_) {
157 throw std::future_error(std::future_errc::no_state);
159 return shared_state_->move();
166 bool valid() const noexcept {
return shared_state_ !=
nullptr; }
169 void wait()
const { shared_state_->wait(); }
179 shared_state) noexcept
180 : shared_state_(std::move(shared_state)) {}
183 std::shared_ptr<detail::ReusableSharedState<R, MutexType, ConditionVariableType>> shared_state_;
186 template <
typename R>
192 template <
typename R,
typename MutexType = std::mutex,
193 typename ConditionVariableType = std::condition_variable>
198 std::make_shared<detail::ReusableSharedState<R, MutexType, ConditionVariableType>>()),
199 future_retrieved_(false) {}
206 : shared_state_(other.shared_state_), future_retrieved_(other.future_retrieved_) {
207 other.shared_state_ =
nullptr;
208 other.future_retrieved_ =
false;
218 shared_state_ = other.shared_state_;
219 future_retrieved_ = other.future_retrieved_;
220 other.shared_state_ =
nullptr;
221 other.future_retrieved_ =
false;
227 if (!shared_state_) {
228 throw std::future_error(std::future_errc::no_state);
230 shared_state_->set(value);
235 if (!shared_state_) {
236 throw std::future_error(std::future_errc::no_state);
238 shared_state_->set(std::move(value));
243 if (!shared_state_) {
244 throw std::future_error(std::future_errc::no_state);
246 if (future_retrieved_) {
247 throw std::future_error(std::future_errc::future_already_retrieved);
249 future_retrieved_ =
true;
255 std::swap(shared_state_, other.shared_state_);
256 std::swap(future_retrieved_, other.future_retrieved_);
260 std::shared_ptr<detail::ReusableSharedState<R, MutexType, ConditionVariableType>> shared_state_;
261 bool future_retrieved_ =
false;
264 template <
typename R>
269 template <
typename R,
typename MutexType,
typename ConditionVariableType>