33 [[nodiscard]]
bool await_ready() const noexcept {
return true; }
50template <
typename T>
using member_read_awaiter_t = std::remove_cvref_t<decltype(std::declval<T>().read())>;
53concept AsyncReadProvider =
requires(T&&
value) { std::forward<T>(
value).read(); } &&
54 TaskAwaitable<member_read_awaiter_t<T>> &&
requires(member_read_awaiter_t<T>& awaiter) {
55 typename member_read_awaiter_t<T>::value_type;
56 { awaiter.await_ready() } -> std::convertible_to<bool>;
57 awaiter.await_resume();
60template <
typename Result>
61using all_result_element_t =
62 std::conditional_t<std::is_lvalue_reference_v<Result>, Result, std::remove_cvref_t<Result>>;
64template <
typename Awaiter>
65using all_result_t = all_result_element_t<decltype(std::declval<Awaiter>().await_resume())>;
70 requires(!detail::AsyncReadProvider<T>)
78 requires detail::AsyncReadProvider<T>
81 return std::forward<T>(
value).read();
90template <TaskFactoryChildAwaitable... Aw>
91 requires((!std::is_void_v<decltype(std::declval<Aw>().await_resume())> && ...))
95 std::array<bool,
sizeof...(Aw)> ready_{};
96 int pending_ =
sizeof...(Aw);
100 [[nodiscard]]
bool await_ready() noexcept {
return await_ready_impl(std::make_index_sequence<
sizeof...(Aw)>{}); }
110 template <
typename F>
void debug_each_dependency(F&& visit)
const
112 std::apply([&](
auto const&... awaiters) { (debug_visit_dependency(awaiters, visit), ...); }, bufs_);
121 await_suspend_impl(std::move(f), std::make_index_sequence<
sizeof...(Aw)>{});
131 return await_resume_impl(std::make_index_sequence<
sizeof...(Aw)>{});
136 template <
typename A,
typename F>
static void debug_visit_dependency(A
const& awaiter, F& visit)
138 if constexpr (
requires {
140 awaiter.debug_task_role();
143 visit(awaiter.node(), awaiter.debug_task_role());
148 template <std::size_t... I>
bool await_ready_impl(std::index_sequence<I...>)
noexcept
151 ((ready_[I] = std::get<I>(bufs_).await_ready(), pending_ += ready_[I] ? 0 : 1), ...);
152 return pending_ == 0;
155 template <std::size_t... I>
void await_suspend_impl(TaskFactory f, std::index_sequence<I...>)
noexcept
157 ((ready_[I] ? void() :
std::get<I>(bufs_).await_suspend(f.take_next())), ...);
160 template <std::
size_t I>
decltype(
auto) await_resume_child()
162 using awaiter_type = std::tuple_element_t<I, std::tuple<Aw...>>;
163 return std::forward<awaiter_type>(std::get<I>(bufs_)).await_resume();
166 template <std::size_t... I>
auto await_resume_impl(std::index_sequence<I...>)
168 using result_type = std::tuple<detail::all_result_t<Aw>...>;
169 return result_type{this->
template await_resume_child<I>()...};
175template <
typename T>
struct MapToRefOrValue
177 static_assert(std::is_trivially_move_constructible_v<T>,
178 "Prvalue passed to all(...) must be trivially move constructible");
182template <
typename T>
struct MapToRefOrValue<T&&>
184 static_assert(std::is_trivially_move_constructible_v<T>,
185 "Rvalue passed to all(...) must be trivially move constructible");
189template <
typename T>
struct MapToRefOrValue<T&>
198template <TaskFactoryChildAwaitable... Aw>
199 requires((!std::is_void_v<decltype(std::declval<Aw>().await_resume())> && ...))
200auto all(Aw&&... aw)
noexcept
203 std::tuple<typename detail::MapToRefOrValue<Aw>::type...>(std::forward<Aw>(aw)...));
229 return std::forward<U>(u).operator
co_await();
233 return operator co_await(std::forward<U>(u));
237 return std::forward<U>(u);
258 auto& inner = access();
259 using ResumeAwaiter = std::conditional_t<std::is_lvalue_reference_v<Awt>,
Awaiter&,
Awaiter&&>;
260 using R =
decltype(std::declval<ResumeAwaiter>().await_resume());
262 std::conditional_t<std::is_lvalue_reference_v<R>, std::reference_wrapper<std::remove_reference_t<R>>,
263 std::remove_cvref_t<R>>;
265 if (!inner.await_ready())
267 return std::optional<StoreT>{};
270 if constexpr (std::is_lvalue_reference_v<R>)
272 return std::optional<StoreT>{std::ref(resume_inner(inner))};
276 return std::optional<StoreT>{resume_inner(inner)};
283 if constexpr (std::is_lvalue_reference_v<Awt>)
285 return std::addressof(aw);
289 return std::move(aw);
293 [[nodiscard]]
constexpr Awaiter& access() noexcept
295 if constexpr (std::is_lvalue_reference_v<Awt>)
305 [[nodiscard]]
constexpr Awaiter const& access() const noexcept
307 if constexpr (std::is_lvalue_reference_v<Awt>)
317 [[nodiscard]]
static decltype(
auto) resume_inner(
Awaiter& inner)
319 if constexpr (std::is_lvalue_reference_v<Awt>)
321 return inner.await_resume();
325 return std::move(inner).await_resume();
355template <
typename Aw>
constexpr auto try_await(Aw&& aw)
noexcept
357 static_assert(std::is_trivially_move_constructible_v<Aw>,
"try_await(x) on prvalues requires T to be safely movable");
379template <
typename T,
typename Value>
class WriteToAwaiter {
381 WriteToAwaiter(WriteBuffer<T>&& buffer, Value&&
value)
382 : buffer_(
std::move(buffer)), value_(
std::forward<Value>(
value))
384 static_assert(std::constructible_from<T, Value&&>,
"Value must be constructible as T for WriteBuffer<T>");
387 [[nodiscard]]
bool await_ready() const noexcept {
return buffer_.await_ready(); }
389 auto await_suspend(BasicTask&& t)
noexcept {
return buffer_.await_suspend(std::move(t)); }
391 void await_resume() { buffer_.emplace_assert(std::move(value_)); }
394 WriteBuffer<T> buffer_;
395 std::remove_reference_t<Value> value_;
411 return detail::WriteToAwaiter<T, Value>(std::move(buffer), std::move(
value));
Awaitable capabilities for shared reads and exclusive mutable access to Async<T>.
Move-only promise-neutral ownership claim for a Uni20 coroutine.
Definition async_task.hpp:103
Factory for producing multiple BasicTask ownership claims for one coroutine.
Definition async_task_promise.hpp:766
Exclusive mutable-access buffer for one Async<T> epoch.
Definition buffers.hpp:859
Detects if a free operator co_await(t) exists.
Definition awaiters.hpp:217
Detects if T has a member operator co_await().
Definition awaiters.hpp:212
locale_t value
Definition data_table.cpp:49
This represents the reverse-mode adjoint for functions of complex variables, assuming a real-valued s...
Definition async/async.hpp:26
auto all(Aw &&... aw) noexcept
Build an awaitable that waits for all of the provided awaitables.
Definition awaiters.hpp:200
decltype(auto) get_awaiter(U &&u) noexcept
for an awaitable a, return the actual Awaitable object returned by co_await
Definition awaiters.hpp:225
ReadBuffer< T > read(Async< T > const &a)
Convenience helper that forwards to Async<T>::read().
Definition async/async.hpp:540
auto write_to(WriteBuffer< T > &&buffer, Value value)
Create a coroutine awaiter that writes a value to a WriteBuffer<T>.
Definition awaiters.hpp:409
constexpr auto try_await(Aw &aw) noexcept
Build a non-blocking awaiter that returns optional<T> instead of suspending.
Definition awaiters.hpp:349
Awaitable that waits for all provided awaiters to complete.
Definition awaiters.hpp:93
void await_suspend(TaskFactory f) noexcept
Suspend the coroutine on awaiters not yet ready.
Definition awaiters.hpp:119
bool await_ready() noexcept
Check if all awaiters are ready.
Definition awaiters.hpp:100
int num_awaiters() const noexcept
Return the number of awaiters, needed by the TaskFactory model.
Definition awaiters.hpp:104
auto await_resume()
Resume all awaiters and collect their results.
Definition awaiters.hpp:129
std::tuple< Aw... > bufs_
Underlying awaiters.
Definition awaiters.hpp:94
Awaiter wrapper that returns an optional result.
Definition awaiters.hpp:244
constexpr TryAwaiter(Awt aw) noexcept
Definition awaiters.hpp:250
StoredAwaiter awaiter_
Definition awaiters.hpp:248
void await_suspend(BasicTask t) noexcept
Definition awaiters.hpp:254
std::remove_reference_t< Awt > Awaiter
Definition awaiters.hpp:245
bool await_ready() const noexcept
Definition awaiters.hpp:252
auto await_resume()
Definition awaiters.hpp:256
std::conditional_t< std::is_lvalue_reference_v< Awt >, Awaiter *, Awt > StoredAwaiter
Definition awaiters.hpp:246
Always-ready awaitable owning an immediate operation value.
Definition awaiters.hpp:27
void release() const noexcept
Match the read-buffer release surface without owning an epoch.
Definition awaiters.hpp:45
T await_resume() &&noexcept
Move the value when the awaiter itself is consumed.
Definition awaiters.hpp:42
bool await_ready() const noexcept
Report that the immediate value never suspends.
Definition awaiters.hpp:33
T value_type
Definition awaiters.hpp:28
T const & await_resume() const &noexcept
Return a borrowed reference when the awaiter is retained.
Definition awaiters.hpp:39
T value
Definition awaiters.hpp:30
void await_suspend(BasicTask) const noexcept
No-op suspension hook required by the awaiter protocol.
Definition awaiters.hpp:36
Async aliases for lazy tensor-level views.