20#include "pw_assert/assert.h"
21#include "pw_async2/future.h"
22#include "pw_polyfill/language_feature_macros.h"
23#include "pw_sync/interrupt_spin_lock.h"
28inline sync::InterruptSpinLock& ValueProviderLock() {
33bool PendValueFutureCore(FutureCore& core, Context& cx)
41class BroadcastValueProvider;
59 *
this = std::move(other);
65 std::lock_guard lock(internal::ValueProviderLock());
66 core_ = std::move(other.core_);
67 value_ = std::move(other.value_);
73 std::lock_guard lock(internal::ValueProviderLock());
79 template <
typename... Args>
81 return ValueFuture(std::in_place, std::forward<Args>(args)...);
91 std::lock_guard lock(internal::ValueProviderLock());
92 if (internal::PendValueFutureCore(core_, cx)) {
95 return Ready(std::move(*value_));
98 [[nodiscard]]
bool is_pendable()
const {
99 std::lock_guard lock(internal::ValueProviderLock());
103 [[nodiscard]]
bool is_complete()
const {
104 std::lock_guard lock(internal::ValueProviderLock());
109 friend class ValueProvider<T>;
110 friend class BroadcastValueProvider<T>;
112 template <
typename... Args>
113 explicit ValueFuture(std::in_place_t, Args&&... args)
114 : core_(FutureState::kReadyForCompletion),
115 value_(std::in_place, std::forward<Args>(args)...) {}
119 template <
typename... Args>
120 void ResolveLocked(Args&&... args)
123 PW_DASSERT(!value_.has_value());
124 value_.emplace(std::forward<Args>(args)...);
128 FutureCore core_
PW_GUARDED_BY(internal::ValueProviderLock());
129 std::optional<T> value_
PW_GUARDED_BY(internal::ValueProviderLock());
137 using value_type = void;
146 std::lock_guard lock(internal::ValueProviderLock());
151 std::lock_guard lock(internal::ValueProviderLock());
152 if (internal::PendValueFutureCore(core_, cx)) {
158 [[nodiscard]]
bool is_pendable()
const {
return core_.
is_pendable(); }
159 [[nodiscard]]
bool is_complete()
const {
return core_.
is_complete(); }
162 return ValueFuture(FutureState::kReadyForCompletion);
170 : core_(FutureState::kReadyForCompletion) {}
205 std::lock_guard lock(internal::ValueProviderLock());
206 list_ = std::move(other.list_);
211 if (
this != &other) {
212 std::lock_guard lock(internal::ValueProviderLock());
213 PW_ASSERT(list_.empty());
214 list_ = std::move(other.list_);
230 std::lock_guard lock(internal::ValueProviderLock());
231 list_.Push(future.core_);
237 template <
typename U = T, std::enable_if_t<!std::is_
void_v<U>,
int> = 0>
239 std::lock_guard lock(internal::ValueProviderLock());
240 list_.ResolveAllWith(
246 template <
typename U = T, std::enable_if_t<std::is_
void_v<U>,
int> = 0>
248 std::lock_guard lock(internal::ValueProviderLock());
275 std::lock_guard lock(internal::ValueProviderLock());
276 list_ = std::move(other.list_);
281 if (
this != &other) {
282 std::lock_guard lock(internal::ValueProviderLock());
283 PW_ASSERT(list_.empty());
284 list_ = std::move(other.list_);
300 std::lock_guard lock(internal::ValueProviderLock());
301 list_.PushRequireEmpty(future.core_);
313 std::lock_guard lock(internal::ValueProviderLock());
314 if (!list_.PushIfEmpty(future.core_)) {
323 std::lock_guard lock(internal::ValueProviderLock());
324 return !list_.empty();
329 template <
typename... Args,
331 std::enable_if_t<!std::is_void_v<U>,
int> = 0>
333 std::lock_guard lock(internal::ValueProviderLock());
334 if (
ValueFuture<T>* future = list_.PopIfAvailable(); future !=
nullptr) {
335 future->ResolveLocked(std::forward<Args>(args)...);
340 template <
typename U = T, std::enable_if_t<std::is_
void_v<U>,
int> = 0>
342 std::lock_guard lock(internal::ValueProviderLock());
343 list_.ResolveOneIfAvailable();
363 provider_ = std::move(other.provider_);
377 template <
typename... Args>
379 provider_.
Resolve(std::in_place, std::forward<Args>(args)...);
402 provider_ = std::move(other.provider_);
Definition: value_future.h:199
ValueFuture< T > Get()
Definition: value_future.h:227
void Resolve(const U &value)
Resolves every pending ValueFuture with a copy of the provided value.
Definition: value_future.h:238
void Resolve()
Resolves every pending ValueFuture.
Definition: value_future.h:247
void WakeAndMarkReady()
Definition: future.h:277
constexpr bool is_pendable() const
Definition: future.h:246
constexpr bool is_complete() const
Definition: future.h:251
void Unlist()
Removes this future from its list, if it is in one.
Definition: future.h:300
Pending
Tag for constructing an active future, for which Pend may be called.
Definition: future.h:114
ReadyForCompletion
Definition: future.h:118
Definition: value_future.h:394
OptionalValueFuture< T > Get()
Definition: value_future.h:415
void Resolve(const T &value)
Resolves all pending ValueFutures with the provided value.
Definition: value_future.h:418
void Cancel()
Resolves all pending ValueFutures with std::nullopt.
Definition: value_future.h:421
Definition: value_future.h:356
void Resolve(Args &&... args)
Resolves the pending ValueFuture by constructing it in-place.
Definition: value_future.h:378
void Cancel()
Resolves the pending ValueFuture with std::nullopt.
Definition: value_future.h:383
OptionalValueFuture< T > Get()
Definition: value_future.h:374
Definition: value_future.h:135
Definition: value_future.h:51
static ValueFuture Resolved(Args &&... args)
Definition: value_future.h:80
Definition: value_future.h:269
ValueFuture< T > Get()
Definition: value_future.h:297
void Resolve(Args &&... args)
Definition: value_future.h:332
bool has_future() const
Returns true if the provider stores a pending future.
Definition: value_future.h:322
void Resolve()
Resolves the pending ValueFuture.
Definition: value_future.h:341
std::optional< ValueFuture< T > > TryGet()
Definition: value_future.h:310
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:353
constexpr Poll Ready()
Returns a value indicating completion.
Definition: poll.h:337
#define PW_CONSTINIT
Definition: language_feature_macros.h:52
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_NO_LOCK_SAFETY_ANALYSIS
Definition: lock_annotations.h:292
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:146
#define PW_LOCKS_EXCLUDED(...)
Definition: lock_annotations.h:176