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"
42 using value_type = void;
43 constexpr Poll<> operator()()
const {
return Ready(); }
61 : ready_(std::move(ready_value_fn)) {}
63 constexpr Poll<T> operator()()
const {
64 return Ready<T>(std::in_place_t{}, ready_());
80template <
typename T,
typename ConstantType,
typename CastType = T>
85 const cpp20::remove_cvref_t<ConstantType>& value)
88 cpp20::remove_cvref_t<ConstantType>&& value)
89 : constant_(std::move(value)) {}
91 constexpr Poll<T> operator()()
const {
92 return Ready<T>(std::in_place_t{}, CastType(constant_));
97 std::is_default_constructible_v<cpp20::remove_cvref_t<ConstantType>>,
98 "ConstantType must be default constructible");
99 cpp20::remove_cvref_t<ConstantType> constant_;
102template <
typename T,
typename CastType>
104 using value_type = T;
108 constexpr Poll<T> operator()()
const {
109 return Ready<T>(std::in_place_t{}, CastType(std::nullopt));
121 std::integral_constant<pw::Status::Code, PW_STATUS_DEADLINE_EXCEEDED>,
145 typename PrimaryFuture,
146 typename TimeoutFuture,
147 typename TimeoutResolution,
148 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>,
149 typename = std::enable_if_t<!std::is_lvalue_reference_v<TimeoutFuture>>,
150 typename = std::enable_if_t<!std::is_lvalue_reference_v<TimeoutResolution>>>
154 "FutureWithTimeout can only be used when PrimaryFuture is a Future type");
157 "FutureWithTimeout can only be used when TimeoutFuture is a Future type");
160 using value_type = T;
165 TimeoutFuture&& timeout_future,
166 TimeoutResolution&& timeout_resolution)
167 : primary_future_(std::move(primary_future)),
168 timeout_future_(std::move(timeout_future)),
169 timeout_resolution_(std::move(timeout_resolution)),
170 state_(FutureState::kPending) {}
172 [[nodiscard]]
constexpr bool is_pendable()
const {
173 return state_.is_pendable();
176 [[nodiscard]]
constexpr bool is_complete()
const {
177 return state_.is_complete();
181 PW_ASSERT(is_pendable());
182 auto result = primary_future_.Pend(cx);
183 if (result.IsReady()) {
184 state_.MarkComplete();
185 return Ready<value_type>(std::in_place, std::move(result).value());
188 if (timeout_future_.Pend(cx).IsReady()) {
189 state_.MarkComplete();
190 return timeout_resolution_();
197 PrimaryFuture primary_future_;
198 TimeoutFuture timeout_future_;
211 typename PrimaryFuture,
212 typename TimeoutFuture,
213 typename TimeoutResolution>
215 TimeoutFuture&& timeout_future,
216 TimeoutResolution&& timeout_resolution)
218 std::decay_t<PrimaryFuture>,
219 std::decay_t<TimeoutFuture>,
220 std::decay_t<TimeoutResolution>> {
222 std::decay_t<PrimaryFuture>,
223 std::decay_t<TimeoutFuture>,
224 std::decay_t<TimeoutResolution>>(
225 std::forward<PrimaryFuture>(primary_future),
226 std::forward<TimeoutFuture>(timeout_future),
227 std::forward<TimeoutResolution>(timeout_resolution));
241 typename PrimaryFuture,
242 typename TimeProvider,
244 int&... kExplicitGuard,
245 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
250 return CreateFutureWithTimeout<ResultType>(
251 std::forward<PrimaryFuture>(primary_future),
268 typename PrimaryFuture,
269 int&... kExplicitGuard,
270 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
274 return CreateFutureWithTimeout<ResultType>(
275 std::forward<PrimaryFuture>(primary_future),
291template <
typename Clock>
294 [[maybe_unused]]
typename Clock::duration delay) {
295 static_assert(
false,
"ValueFuture<void> cannot be used with TimeoutOr");
310template <
typename PrimaryFuture,
typename Clock,
typename U>
313 typename Clock::duration delay,
314 U&& value_or_fn_on_timeout) {
315 using value_type =
typename PrimaryFuture::value_type;
318 std::is_invocable_v<U> || std::is_convertible_v<U, value_type>,
319 "value_or_fn_on_timeout (U) must be callable, or convert to the "
320 "value_type of the primary_future");
322 if constexpr (std::is_invocable_v<U>) {
323 return CreateFutureWithTimeout<value_type>(
324 std::forward<PrimaryFuture>(primary_future),
327 std::forward<U>(value_or_fn_on_timeout)));
328 }
else if constexpr (std::is_convertible_v<U, value_type>) {
329 return CreateFutureWithTimeout<value_type>(
330 std::forward<PrimaryFuture>(primary_future),
333 std::forward<U>(value_or_fn_on_timeout)));
345 typename PrimaryFuture,
347 int&... kExplicitGuard,
348 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
352 return TimeoutOr<typename std::decay_t<PrimaryFuture>>(
353 std::forward<PrimaryFuture>(primary_future),
356 std::forward<Args>(args)...);
369template <
typename T,
typename Clock>
372 typename Clock::duration delay) {
373 return CreateFutureWithTimeout<std::optional<T>>(
390template <
typename T,
typename Clock>
393 typename Clock::duration delay) {
394 return CreateFutureWithTimeout<T>(
410template <
typename T,
typename Clock>
413 typename Clock::duration delay) {
414 using ResultType =
typename ReserveSendFuture<T>::value_type;
415 return CreateFutureWithTimeout<ResultType>(
419 std::nullopt_t>(std::nullopt));
430 typename PrimaryFuture,
431 int&... kExplicitGuard,
432 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
442template <
typename T,
typename Clock = chrono::SystemClock>
446 std::declval<typename Clock::duration>()));
454template <
typename T,
typename U,
typename Clock = chrono::SystemClock>
458 std::declval<typename Clock::duration>(),
459 std::declval<U&&>()));
464template <
typename T,
typename Clock = chrono::SystemClock>
468 std::declval<typename Clock::duration>()));
476template <
typename T,
typename U,
typename Clock = chrono::SystemClock>
480 std::declval<typename Clock::duration>(),
481 std::declval<U&&>()));
485template <
typename T,
typename Clock = chrono::SystemClock>
489 std::declval<typename Clock::duration>()));
494template <
typename T,
typename Clock = chrono::SystemClock>
498 std::declval<typename Clock::duration>()));
503template <
typename T,
typename Clock = chrono::SystemClock>
507 std::declval<typename Clock::duration>()));
512template <
typename T,
typename Clock = chrono::SystemClock>
516 std::declval<typename Clock::duration>()));
521template <
typename T,
typename Clock = chrono::SystemClock>
525 std::declval<typename Clock::duration>()));
530template <
typename T,
typename Clock = chrono::SystemClock>
534 std::declval<typename Clock::duration>()));
539template <
typename FutureType,
typename Clock = chrono::SystemClock>
541 decltype(
Timeout(std::declval<FutureType&&>(),
543 std::declval<typename Clock::duration>()));
551template <
typename FutureType,
typename U,
typename Clock = chrono::SystemClock>
553 decltype(
TimeoutOr(std::declval<FutureType&&>(),
555 std::declval<typename Clock::duration>(),
556 std::declval<U&&>()));
Definition: future_timeout.h:151
Definition: channel.h:771
Definition: channel.h:1095
Definition: channel.h:975
Definition: channel.h:1042
Definition: time_provider.h:63
TimeFuture< Clock > WaitFor(typename Clock::duration delay)
Definition: time_provider.h:75
Definition: value_future.h:51
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
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:214
decltype(Timeout(std::declval< ReceiveFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReceiveFutureWithTimeout
Definition: future_timeout.h:498
decltype(Timeout(std::declval< ReserveSendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReserveSendFutureWithTimeout
Definition: future_timeout.h:507
decltype(Timeout(std::declval< ValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ValueFutureWithTimeout
Definition: future_timeout.h:446
decltype(TimeoutOrClosed(std::declval< ReceiveFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReceiveFutureWithTimeoutOrClosed
Definition: future_timeout.h:525
TimeProvider< chrono::SystemClock > & GetSystemTimeProvider()
Returns a TimeProvider using the "real" SystemClock and SystemTimer.
decltype(TimeoutOr(std::declval< OptionalValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >(), std::declval< U && >())) OptionalValueFutureWithTimeoutOr
Definition: future_timeout.h:481
decltype(Timeout(std::declval< SendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) SendFutureWithTimeout
Definition: future_timeout.h:489
auto Timeout(PrimaryFuture &&primary_future, TimeProvider &time_provider, Duration delay)
Definition: future_timeout.h:246
auto TimeoutOrClosed(ReceiveFuture< T > &&future, TimeProvider< Clock > &time_provider, typename Clock::duration delay)
Definition: future_timeout.h:370
decltype(Timeout(std::declval< OptionalValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) OptionalValueFutureWithTimeout
Definition: future_timeout.h:468
decltype(TimeoutOrClosed(std::declval< SendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) SendFutureWithTimeoutOrClosed
Definition: future_timeout.h:516
decltype(Timeout(std::declval< FutureType && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) CustomFutureWithTimeout
Definition: future_timeout.h:543
decltype(TimeoutOr(std::declval< FutureType && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >(), std::declval< U && >())) CustomFutureWithTimeoutOr
Definition: future_timeout.h:556
decltype(TimeoutOrClosed(std::declval< ReserveSendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReserveSendFutureWithTimeoutOrClosed
Definition: future_timeout.h:534
void TimeoutOr(ValueFuture< void > &&future, TimeProvider< Clock > &time_provider, typename Clock::duration delay)
Definition: future_timeout.h:292
decltype(TimeoutOr(std::declval< ValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >(), std::declval< U && >())) ValueFutureWithTimeoutOr
Definition: future_timeout.h:459
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:81
Definition: future_timeout.h:53
constexpr ReadyFunctionResultResolution()=default
Cannot be invoked when default constructed; will crash.