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;
143 *
this = std::move(other);
148 if (
this != &other) {
149 std::lock_guard lock(internal::ValueProviderLock());
150 core_ = std::move(other.core_);
156 std::lock_guard lock(internal::ValueProviderLock());
161 std::lock_guard lock(internal::ValueProviderLock());
162 if (internal::PendValueFutureCore(core_, cx)) {
168 [[nodiscard]]
bool is_pendable()
const {
169 std::lock_guard lock(internal::ValueProviderLock());
173 [[nodiscard]]
bool is_complete()
const {
174 std::lock_guard lock(internal::ValueProviderLock());
179 return ValueFuture(FutureState::kReadyForCompletion);
187 : core_(FutureState::kReadyForCompletion) {}
222 std::lock_guard lock(internal::ValueProviderLock());
223 list_ = std::move(other.list_);
228 if (
this != &other) {
229 std::lock_guard lock(internal::ValueProviderLock());
230 PW_ASSERT(list_.empty());
231 list_ = std::move(other.list_);
247 std::lock_guard lock(internal::ValueProviderLock());
248 list_.Push(future.core_);
254 template <
typename U = T, std::enable_if_t<!std::is_
void_v<U>,
int> = 0>
256 std::lock_guard lock(internal::ValueProviderLock());
257 list_.ResolveAllWith(
263 template <
typename U = T, std::enable_if_t<std::is_
void_v<U>,
int> = 0>
265 std::lock_guard lock(internal::ValueProviderLock());
292 std::lock_guard lock(internal::ValueProviderLock());
293 list_ = std::move(other.list_);
298 if (
this != &other) {
299 std::lock_guard lock(internal::ValueProviderLock());
300 PW_ASSERT(list_.empty());
301 list_ = std::move(other.list_);
317 std::lock_guard lock(internal::ValueProviderLock());
318 list_.PushRequireEmpty(future.core_);
330 std::lock_guard lock(internal::ValueProviderLock());
331 if (!list_.PushIfEmpty(future.core_)) {
340 std::lock_guard lock(internal::ValueProviderLock());
341 return !list_.empty();
346 template <
typename... Args,
348 std::enable_if_t<!std::is_void_v<U>,
int> = 0>
350 std::lock_guard lock(internal::ValueProviderLock());
351 if (
ValueFuture<T>* future = list_.PopIfAvailable(); future !=
nullptr) {
352 future->ResolveLocked(std::forward<Args>(args)...);
357 template <
typename U = T, std::enable_if_t<std::is_
void_v<U>,
int> = 0>
359 std::lock_guard lock(internal::ValueProviderLock());
360 list_.ResolveOneIfAvailable();
380 provider_ = std::move(other.provider_);
394 template <
typename... Args>
396 provider_.
Resolve(std::in_place, std::forward<Args>(args)...);
419 provider_ = std::move(other.provider_);
Definition: value_future.h:216
ValueFuture< T > Get()
Definition: value_future.h:244
void Resolve(const U &value)
Resolves every pending ValueFuture with a copy of the provided value.
Definition: value_future.h:255
void Resolve()
Resolves every pending ValueFuture.
Definition: value_future.h:264
void WakeAndMarkReady()
Definition: future.h:286
constexpr bool is_pendable() const
Definition: future.h:255
constexpr bool is_complete() const
Definition: future.h:260
void Unlist()
Removes this future from its list, if it is in one.
Definition: future.h:309
Pending
Tag for constructing an active future, for which Pend may be called.
Definition: future.h:117
ReadyForCompletion
Definition: future.h:121
Definition: value_future.h:411
OptionalValueFuture< T > Get()
Definition: value_future.h:432
void Resolve(const T &value)
Resolves all pending ValueFutures with the provided value.
Definition: value_future.h:435
void Cancel()
Resolves all pending ValueFutures with std::nullopt.
Definition: value_future.h:438
Definition: value_future.h:373
void Resolve(Args &&... args)
Resolves the pending ValueFuture by constructing it in-place.
Definition: value_future.h:395
void Cancel()
Resolves the pending ValueFuture with std::nullopt.
Definition: value_future.h:400
OptionalValueFuture< T > Get()
Definition: value_future.h:391
Definition: value_future.h:135
Definition: value_future.h:51
static ValueFuture Resolved(Args &&... args)
Definition: value_future.h:80
Definition: value_future.h:286
ValueFuture< T > Get()
Definition: value_future.h:314
void Resolve(Args &&... args)
Definition: value_future.h:349
bool has_future() const
Returns true if the provider stores a pending future.
Definition: value_future.h:339
void Resolve()
Resolves the pending ValueFuture.
Definition: value_future.h:358
std::optional< ValueFuture< T > > TryGet()
Definition: value_future.h:327
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:296
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:147
#define PW_LOCKS_EXCLUDED(...)
Definition: lock_annotations.h:178