21#include "lib/stdcompat/type_traits.h"
22#include "pw_assert/assert.h"
23#include "pw_async2/channel.h"
24#include "pw_async2/context.h"
25#include "pw_async2/future.h"
26#include "pw_async2/poll.h"
27#include "pw_async2/system_time_provider.h"
28#include "pw_async2/time_provider.h"
29#include "pw_async2/value_future.h"
30#include "pw_chrono/system_clock.h"
31#include "pw_function/function.h"
32#include "pw_preprocessor/compiler.h"
33#include "pw_status/status.h"
43 constexpr Poll<> operator()()
const {
return Ready(); }
57 : ready_(std::move(ready_value_fn)) {}
59 constexpr Poll<T> operator()()
const {
60 return Ready<T>(std::in_place_t{}, ready_());
76template <
typename T,
typename ConstantType,
typename CastType = T>
81 const cpp20::remove_cvref_t<ConstantType>& value)
84 cpp20::remove_cvref_t<ConstantType>&& value)
85 : constant_(std::move(value)) {}
87 constexpr Poll<T> operator()()
const {
88 return Ready<T>(std::in_place_t{}, CastType(constant_));
92 cpp20::remove_cvref_t<ConstantType> constant_;
103 std::integral_constant<pw::Status::Code, PW_STATUS_DEADLINE_EXCEEDED>,
127 typename PrimaryFuture,
128 typename TimeoutFuture,
129 typename TimeoutResolution,
130 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>,
131 typename = std::enable_if_t<!std::is_lvalue_reference_v<TimeoutFuture>>,
132 typename = std::enable_if_t<!std::is_lvalue_reference_v<TimeoutResolution>>>
135 FutureWithTimeout<T, PrimaryFuture, TimeoutFuture, TimeoutResolution>,
138 is_future_v<PrimaryFuture>,
139 "FutureWithTimeout can only be used when PrimaryFuture is a Future type");
141 is_future_v<TimeoutFuture>,
142 "FutureWithTimeout can only be used when TimeoutFuture is a Future type");
146 TimeoutFuture&& timeout_future,
147 TimeoutResolution&& timeout_resolution)
148 : state_{std::in_place,
149 State{.primary_future = std::move(primary_future),
150 .timeout_future_ = std::move(timeout_future),
151 .timeout_resolution_ = std::move(timeout_resolution)}} {}
160 PW_DASSERT(state_.has_value());
161 auto result = state_->primary_future.Pend(cx);
162 if (result.IsReady()) {
163 return Ready<typename Base::value_type>(std::in_place_t{},
164 std::move(result).value());
167 if (state_->timeout_future_.Pend(cx).IsReady()) {
168 return state_->timeout_resolution_();
174 void DoMarkComplete() { state_.reset(); }
175 [[nodiscard]]
bool DoIsComplete()
const {
return !state_.has_value(); }
178 PrimaryFuture primary_future;
179 TimeoutFuture timeout_future_;
182 std::optional<State> state_;
193 typename PrimaryFuture,
194 typename TimeoutFuture,
195 typename TimeoutResolution>
197 TimeoutFuture&& timeout_future,
198 TimeoutResolution&& timeout_resolution)
200 std::decay_t<PrimaryFuture>,
201 std::decay_t<TimeoutFuture>,
202 std::decay_t<TimeoutResolution>> {
204 std::decay_t<PrimaryFuture>,
205 std::decay_t<TimeoutFuture>,
206 std::decay_t<TimeoutResolution>>(
207 std::forward<PrimaryFuture>(primary_future),
208 std::forward<TimeoutFuture>(timeout_future),
209 std::forward<TimeoutResolution>(timeout_resolution));
223 typename PrimaryFuture,
224 typename TimeProvider,
226 int&... kExplicitGuard,
227 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
232 return CreateFutureWithTimeout<ResultType>(
233 std::forward<PrimaryFuture>(primary_future),
250 typename PrimaryFuture,
251 int&... kExplicitGuard,
252 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
256 return CreateFutureWithTimeout<ResultType>(
257 std::forward<PrimaryFuture>(primary_future),
273template <
typename Clock>
276 [[maybe_unused]]
typename Clock::duration delay) {
277 static_assert(
false,
"ValueFuture<void> cannot be used with TimeoutOr");
292template <
typename PrimaryFuture,
typename Clock,
typename U>
295 typename Clock::duration delay,
296 U&& value_or_fn_on_timeout) {
297 using value_type =
typename PrimaryFuture::value_type;
300 std::is_invocable_v<U> || std::is_convertible_v<U, value_type>,
301 "value_or_fn_on_timeout (U) must be callable, or convert to the "
302 "value_type of the primary_future");
304 if constexpr (std::is_invocable_v<U>) {
305 return CreateFutureWithTimeout<value_type>(
306 std::forward<PrimaryFuture>(primary_future),
309 std::forward<U>(value_or_fn_on_timeout)));
310 }
else if constexpr (std::is_convertible_v<U, value_type>) {
311 return CreateFutureWithTimeout<value_type>(
312 std::forward<PrimaryFuture>(primary_future),
315 std::forward<U>(value_or_fn_on_timeout)));
327 typename PrimaryFuture,
329 int&... kExplicitGuard,
330 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
334 return TimeoutOr<typename std::decay_t<PrimaryFuture>>(
335 std::forward<PrimaryFuture>(primary_future),
338 std::forward<Args>(args)...);
351template <
typename T,
typename Clock>
354 typename Clock::duration delay) {
355 return CreateFutureWithTimeout<std::optional<T>>(
372template <
typename T,
typename Clock>
375 typename Clock::duration delay) {
376 return CreateFutureWithTimeout<T>(
392template <
typename T,
typename Clock>
395 typename Clock::duration delay) {
396 using ResultType =
typename ReserveSendFuture<T>::value_type;
397 return CreateFutureWithTimeout<ResultType>(
401 std::nullopt_t>(std::nullopt));
412 typename PrimaryFuture,
413 int&... kExplicitGuard,
414 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
424template <
typename T,
typename Clock = chrono::SystemClock>
428 std::declval<typename Clock::duration>()));
436template <
typename T,
typename U,
typename Clock = chrono::SystemClock>
440 std::declval<typename Clock::duration>(),
441 std::declval<U&&>()));
445template <
typename T,
typename Clock = chrono::SystemClock>
449 std::declval<typename Clock::duration>()));
454template <
typename T,
typename Clock = chrono::SystemClock>
458 std::declval<typename Clock::duration>()));
463template <
typename T,
typename Clock = chrono::SystemClock>
467 std::declval<typename Clock::duration>()));
472template <
typename T,
typename Clock = chrono::SystemClock>
476 std::declval<typename Clock::duration>()));
481template <
typename T,
typename Clock = chrono::SystemClock>
485 std::declval<typename Clock::duration>()));
490template <
typename T,
typename Clock = chrono::SystemClock>
494 std::declval<typename Clock::duration>()));
499template <
typename FutureType,
typename Clock = chrono::SystemClock>
501 decltype(
Timeout(std::declval<FutureType&&>(),
503 std::declval<typename Clock::duration>()));
511template <
typename FutureType,
typename U,
typename Clock = chrono::SystemClock>
513 decltype(
TimeoutOr(std::declval<FutureType&&>(),
515 std::declval<typename Clock::duration>(),
516 std::declval<U&&>()));
Definition: future_timeout.h:136
Definition: channel.h:770
Definition: channel.h:1088
Definition: channel.h:972
Definition: channel.h:1035
Definition: time_provider.h:63
TimeFuture< Clock > WaitFor(typename Clock::duration delay)
Definition: time_provider.h:75
Definition: value_future.h:46
constexpr PendingType Pending()
Returns a value indicating that an operation was not yet able to complete.
Definition: poll.h:271
constexpr Poll Ready()
Returns a value indicating completion.
Definition: poll.h:255
auto CreateFutureWithTimeout(PrimaryFuture &&primary_future, TimeoutFuture &&timeout_future, TimeoutResolution &&timeout_resolution) -> FutureWithTimeout< T, std::decay_t< PrimaryFuture >, std::decay_t< TimeoutFuture >, std::decay_t< TimeoutResolution > >
Definition: future_timeout.h:196
decltype(Timeout(std::declval< ReceiveFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReceiveFutureWithTimeout
Definition: future_timeout.h:458
decltype(Timeout(std::declval< ReserveSendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReserveSendFutureWithTimeout
Definition: future_timeout.h:467
decltype(Timeout(std::declval< ValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ValueFutureWithTimeout
Definition: future_timeout.h:428
decltype(TimeoutOrClosed(std::declval< ReceiveFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReceiveFutureWithTimeoutOrClosed
Definition: future_timeout.h:485
TimeProvider< chrono::SystemClock > & GetSystemTimeProvider()
Returns a TimeProvider using the "real" SystemClock and SystemTimer.
decltype(Timeout(std::declval< SendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) SendFutureWithTimeout
Definition: future_timeout.h:449
auto Timeout(PrimaryFuture &&primary_future, TimeProvider &time_provider, Duration delay)
Definition: future_timeout.h:228
auto TimeoutOrClosed(ReceiveFuture< T > &&future, TimeProvider< Clock > &time_provider, typename Clock::duration delay)
Definition: future_timeout.h:352
decltype(TimeoutOrClosed(std::declval< SendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) SendFutureWithTimeoutOrClosed
Definition: future_timeout.h:476
decltype(Timeout(std::declval< FutureType && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) CustomFutureWithTimeout
Definition: future_timeout.h:503
decltype(TimeoutOr(std::declval< FutureType && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >(), std::declval< U && >())) CustomFutureWithTimeoutOr
Definition: future_timeout.h:516
decltype(TimeoutOrClosed(std::declval< ReserveSendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReserveSendFutureWithTimeoutOrClosed
Definition: future_timeout.h:494
void TimeoutOr(ValueFuture< void > &&future, TimeProvider< Clock > &time_provider, typename Clock::duration delay)
Definition: future_timeout.h:274
decltype(TimeoutOr(std::declval< ValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >(), std::declval< U && >())) ValueFutureWithTimeoutOr
Definition: future_timeout.h:441
std::chrono::duration< rep, period > duration
Alias for durations representable with this clock.
Definition: system_clock.h:90
fit::function_impl< function_internal::config::kInlineCallableSize, !function_internal::config::kEnableDynamicAllocation, FunctionType, PW_FUNCTION_DEFAULT_ALLOCATOR_TYPE > Function
Definition: function.h:73
#define PW_NO_UNIQUE_ADDRESS
Definition: compiler.h:297
Definition: future_timeout.h:41
Definition: future_timeout.h:77
Definition: future_timeout.h:53