19#include "pw_assert/assert.h"
20#include "pw_async2/future.h"
21#include "pw_polyfill/language_feature_macros.h"
22#include "pw_sync/interrupt_spin_lock.h"
27inline sync::InterruptSpinLock& ValueProviderLock() {
37class BroadcastValueProvider;
55 *
this = std::move(other);
61 std::lock_guard lock(internal::ValueProviderLock());
62 core_ = std::move(other.core_);
63 value_ = std::move(other.value_);
69 std::lock_guard lock(internal::ValueProviderLock());
75 template <
typename... Args>
77 return ValueFuture(std::in_place, std::forward<Args>(args)...);
87 std::lock_guard lock(internal::ValueProviderLock());
91 [[nodiscard]]
bool is_pendable()
const {
92 std::lock_guard lock(internal::ValueProviderLock());
96 [[nodiscard]]
bool is_complete()
const {
97 std::lock_guard lock(internal::ValueProviderLock());
102 friend class FutureCore;
103 friend class ValueProvider<T>;
104 friend class BroadcastValueProvider<T>;
106 static constexpr char kWaitReason[] =
"ValueFuture";
108 template <
typename... Args>
109 explicit ValueFuture(std::in_place_t, Args&&... args)
110 : core_(FutureState::kReadyForCompletion),
111 value_(std::in_place, std::forward<Args>(args)...) {}
115 Poll<T> DoPend(Context&)
121 return Ready(std::move(*value_));
124 template <
typename... Args>
125 void ResolveLocked(Args&&... args)
128 PW_DASSERT(!value_.has_value());
129 value_.emplace(std::forward<Args>(args)...);
133 FutureCore core_
PW_GUARDED_BY(internal::ValueProviderLock());
134 std::optional<T> value_
PW_GUARDED_BY(internal::ValueProviderLock());
142 using value_type = void;
151 std::lock_guard lock(internal::ValueProviderLock());
156 std::lock_guard lock(internal::ValueProviderLock());
160 [[nodiscard]]
bool is_pendable()
const {
return core_.
is_pendable(); }
161 [[nodiscard]]
bool is_complete()
const {
return core_.
is_complete(); }
164 return ValueFuture(FutureState::kReadyForCompletion);
167 static constexpr char kWaitReason[] =
"ValueFuture<void>";
175 : core_(FutureState::kReadyForCompletion) {}
217 std::lock_guard lock(internal::ValueProviderLock());
218 list_ = std::move(other.list_);
223 if (
this != &other) {
224 std::lock_guard lock(internal::ValueProviderLock());
225 PW_ASSERT(list_.empty());
226 list_ = std::move(other.list_);
242 std::lock_guard lock(internal::ValueProviderLock());
243 list_.Push(future.core_);
249 template <
typename U = T, std::enable_if_t<!std::is_
void_v<U>,
int> = 0>
251 std::lock_guard lock(internal::ValueProviderLock());
252 list_.ResolveAllWith(
258 template <
typename U = T, std::enable_if_t<std::is_
void_v<U>,
int> = 0>
260 std::lock_guard lock(internal::ValueProviderLock());
287 std::lock_guard lock(internal::ValueProviderLock());
288 list_ = std::move(other.list_);
293 if (
this != &other) {
294 std::lock_guard lock(internal::ValueProviderLock());
295 PW_ASSERT(list_.empty());
296 list_ = std::move(other.list_);
312 std::lock_guard lock(internal::ValueProviderLock());
313 list_.PushRequireEmpty(future);
325 std::lock_guard lock(internal::ValueProviderLock());
326 if (!list_.PushIfEmpty(future.core_)) {
335 std::lock_guard lock(internal::ValueProviderLock());
336 return !list_.empty();
341 template <
typename... Args,
343 std::enable_if_t<!std::is_void_v<U>,
int> = 0>
345 std::lock_guard lock(internal::ValueProviderLock());
346 if (
ValueFuture<T>* future = list_.PopIfAvailable(); future !=
nullptr) {
347 future->ResolveLocked(std::forward<Args>(args)...);
352 template <
typename U = T, std::enable_if_t<std::is_
void_v<U>,
int> = 0>
354 std::lock_guard lock(internal::ValueProviderLock());
355 list_.ResolveOneIfAvailable();
375 provider_ = std::move(other.provider_);
389 template <
typename... Args>
391 provider_.
Resolve(std::in_place, std::forward<Args>(args)...);
414 provider_ = std::move(other.provider_);
Definition: value_future.h:211
ValueFuture< T > Get()
Definition: value_future.h:239
void Resolve(const U &value)
Resolves every pending ValueFuture with a copy of the provided value.
Definition: value_future.h:250
void Resolve()
Resolves every pending ValueFuture.
Definition: value_future.h:259
void WakeAndMarkReady()
Definition: future.h:267
constexpr bool is_pendable() const
Definition: future.h:239
constexpr bool is_complete() const
Definition: future.h:244
auto DoPend(FutureType &future, Context &cx)
Definition: future.h:305
void Unlist()
Removes this future from its list, if it is in one.
Definition: future.h:287
constexpr bool is_ready() const
Definition: future.h:254
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:406
OptionalValueFuture< T > Get()
Definition: value_future.h:427
void Resolve(const T &value)
Resolves all pending ValueFutures with the provided value.
Definition: value_future.h:430
void Cancel()
Resolves all pending ValueFutures with std::nullopt.
Definition: value_future.h:433
Definition: value_future.h:368
void Resolve(Args &&... args)
Resolves the pending ValueFuture by constructing it in-place.
Definition: value_future.h:390
void Cancel()
Resolves the pending ValueFuture with std::nullopt.
Definition: value_future.h:395
OptionalValueFuture< T > Get()
Definition: value_future.h:386
Definition: value_future.h:140
Definition: value_future.h:47
static ValueFuture Resolved(Args &&... args)
Definition: value_future.h:76
Definition: value_future.h:281
ValueFuture< T > Get()
Definition: value_future.h:309
void Resolve(Args &&... args)
Definition: value_future.h:344
bool has_future() const
Returns true if the provider stores a pending future.
Definition: value_future.h:334
void Resolve()
Resolves the pending ValueFuture.
Definition: value_future.h:353
std::optional< ValueFuture< T > > TryGet()
Definition: value_future.h:322
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