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_));
96 cpp20::remove_cvref_t<ConstantType> constant_;
107 std::integral_constant<pw::Status::Code, PW_STATUS_DEADLINE_EXCEEDED>,
131 typename PrimaryFuture,
132 typename TimeoutFuture,
133 typename TimeoutResolution,
134 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>,
135 typename = std::enable_if_t<!std::is_lvalue_reference_v<TimeoutFuture>>,
136 typename = std::enable_if_t<!std::is_lvalue_reference_v<TimeoutResolution>>>
140 "FutureWithTimeout can only be used when PrimaryFuture is a Future type");
143 "FutureWithTimeout can only be used when TimeoutFuture is a Future type");
146 using value_type = T;
151 TimeoutFuture&& timeout_future,
152 TimeoutResolution&& timeout_resolution)
153 : primary_future_(std::move(primary_future)),
154 timeout_future_(std::move(timeout_future)),
155 timeout_resolution_(std::move(timeout_resolution)),
156 state_(FutureState::kPending) {}
158 [[nodiscard]]
constexpr bool is_pendable()
const {
159 return state_.is_pendable();
162 [[nodiscard]]
constexpr bool is_complete()
const {
163 return state_.is_complete();
167 PW_ASSERT(is_pendable());
168 auto result = primary_future_.Pend(cx);
169 if (result.IsReady()) {
170 state_.MarkComplete();
171 return Ready<value_type>(std::in_place, std::move(result).value());
174 if (timeout_future_.Pend(cx).IsReady()) {
175 state_.MarkComplete();
176 return timeout_resolution_();
183 PrimaryFuture primary_future_;
184 TimeoutFuture timeout_future_;
197 typename PrimaryFuture,
198 typename TimeoutFuture,
199 typename TimeoutResolution>
201 TimeoutFuture&& timeout_future,
202 TimeoutResolution&& timeout_resolution)
204 std::decay_t<PrimaryFuture>,
205 std::decay_t<TimeoutFuture>,
206 std::decay_t<TimeoutResolution>> {
208 std::decay_t<PrimaryFuture>,
209 std::decay_t<TimeoutFuture>,
210 std::decay_t<TimeoutResolution>>(
211 std::forward<PrimaryFuture>(primary_future),
212 std::forward<TimeoutFuture>(timeout_future),
213 std::forward<TimeoutResolution>(timeout_resolution));
227 typename PrimaryFuture,
228 typename TimeProvider,
230 int&... kExplicitGuard,
231 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
236 return CreateFutureWithTimeout<ResultType>(
237 std::forward<PrimaryFuture>(primary_future),
254 typename PrimaryFuture,
255 int&... kExplicitGuard,
256 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
260 return CreateFutureWithTimeout<ResultType>(
261 std::forward<PrimaryFuture>(primary_future),
277template <
typename Clock>
280 [[maybe_unused]]
typename Clock::duration delay) {
281 static_assert(
false,
"ValueFuture<void> cannot be used with TimeoutOr");
296template <
typename PrimaryFuture,
typename Clock,
typename U>
299 typename Clock::duration delay,
300 U&& value_or_fn_on_timeout) {
301 using value_type =
typename PrimaryFuture::value_type;
304 std::is_invocable_v<U> || std::is_convertible_v<U, value_type>,
305 "value_or_fn_on_timeout (U) must be callable, or convert to the "
306 "value_type of the primary_future");
308 if constexpr (std::is_invocable_v<U>) {
309 return CreateFutureWithTimeout<value_type>(
310 std::forward<PrimaryFuture>(primary_future),
313 std::forward<U>(value_or_fn_on_timeout)));
314 }
else if constexpr (std::is_convertible_v<U, value_type>) {
315 return CreateFutureWithTimeout<value_type>(
316 std::forward<PrimaryFuture>(primary_future),
319 std::forward<U>(value_or_fn_on_timeout)));
331 typename PrimaryFuture,
333 int&... kExplicitGuard,
334 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
338 return TimeoutOr<typename std::decay_t<PrimaryFuture>>(
339 std::forward<PrimaryFuture>(primary_future),
342 std::forward<Args>(args)...);
355template <
typename T,
typename Clock>
358 typename Clock::duration delay) {
359 return CreateFutureWithTimeout<std::optional<T>>(
376template <
typename T,
typename Clock>
379 typename Clock::duration delay) {
380 return CreateFutureWithTimeout<T>(
396template <
typename T,
typename Clock>
399 typename Clock::duration delay) {
400 using ResultType =
typename ReserveSendFuture<T>::value_type;
401 return CreateFutureWithTimeout<ResultType>(
405 std::nullopt_t>(std::nullopt));
416 typename PrimaryFuture,
417 int&... kExplicitGuard,
418 typename = std::enable_if_t<!std::is_lvalue_reference_v<PrimaryFuture>>>
428template <
typename T,
typename Clock = chrono::SystemClock>
432 std::declval<typename Clock::duration>()));
440template <
typename T,
typename U,
typename Clock = chrono::SystemClock>
444 std::declval<typename Clock::duration>(),
445 std::declval<U&&>()));
450template <
typename T,
typename Clock = chrono::SystemClock>
454 std::declval<typename Clock::duration>()));
462template <
typename T,
typename U,
typename Clock = chrono::SystemClock>
466 std::declval<typename Clock::duration>(),
467 std::declval<U&&>()));
471template <
typename T,
typename Clock = chrono::SystemClock>
475 std::declval<typename Clock::duration>()));
480template <
typename T,
typename Clock = chrono::SystemClock>
484 std::declval<typename Clock::duration>()));
489template <
typename T,
typename Clock = chrono::SystemClock>
493 std::declval<typename Clock::duration>()));
498template <
typename T,
typename Clock = chrono::SystemClock>
502 std::declval<typename Clock::duration>()));
507template <
typename T,
typename Clock = chrono::SystemClock>
511 std::declval<typename Clock::duration>()));
516template <
typename T,
typename Clock = chrono::SystemClock>
520 std::declval<typename Clock::duration>()));
525template <
typename FutureType,
typename Clock = chrono::SystemClock>
527 decltype(
Timeout(std::declval<FutureType&&>(),
529 std::declval<typename Clock::duration>()));
537template <
typename FutureType,
typename U,
typename Clock = chrono::SystemClock>
539 decltype(
TimeoutOr(std::declval<FutureType&&>(),
541 std::declval<typename Clock::duration>(),
542 std::declval<U&&>()));
Definition: future_timeout.h:137
Definition: channel.h:768
Definition: channel.h:1090
Definition: channel.h:971
Definition: channel.h:1037
Definition: time_provider.h:63
TimeFuture< Clock > WaitFor(typename Clock::duration delay)
Definition: time_provider.h:75
Definition: value_future.h:47
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:200
decltype(Timeout(std::declval< ReceiveFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReceiveFutureWithTimeout
Definition: future_timeout.h:484
decltype(Timeout(std::declval< ReserveSendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReserveSendFutureWithTimeout
Definition: future_timeout.h:493
decltype(Timeout(std::declval< ValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ValueFutureWithTimeout
Definition: future_timeout.h:432
decltype(TimeoutOrClosed(std::declval< ReceiveFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReceiveFutureWithTimeoutOrClosed
Definition: future_timeout.h:511
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:467
decltype(Timeout(std::declval< SendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) SendFutureWithTimeout
Definition: future_timeout.h:475
auto Timeout(PrimaryFuture &&primary_future, TimeProvider &time_provider, Duration delay)
Definition: future_timeout.h:232
auto TimeoutOrClosed(ReceiveFuture< T > &&future, TimeProvider< Clock > &time_provider, typename Clock::duration delay)
Definition: future_timeout.h:356
decltype(Timeout(std::declval< OptionalValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) OptionalValueFutureWithTimeout
Definition: future_timeout.h:454
decltype(TimeoutOrClosed(std::declval< SendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) SendFutureWithTimeoutOrClosed
Definition: future_timeout.h:502
decltype(Timeout(std::declval< FutureType && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) CustomFutureWithTimeout
Definition: future_timeout.h:529
decltype(TimeoutOr(std::declval< FutureType && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >(), std::declval< U && >())) CustomFutureWithTimeoutOr
Definition: future_timeout.h:542
decltype(TimeoutOrClosed(std::declval< ReserveSendFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >())) ReserveSendFutureWithTimeoutOrClosed
Definition: future_timeout.h:520
void TimeoutOr(ValueFuture< void > &&future, TimeProvider< Clock > &time_provider, typename Clock::duration delay)
Definition: future_timeout.h:278
decltype(TimeoutOr(std::declval< ValueFuture< T > && >(), std::declval< TimeProvider< Clock > & >(), std::declval< typename Clock::duration >(), std::declval< U && >())) ValueFutureWithTimeoutOr
Definition: future_timeout.h:445
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.