29template <
typename T>
class Async;
31template <
typename T>
class ReadMaybeAwaiter;
32template <
typename T>
class ReadOrCancelAwaiter;
33template <
typename T>
class OwningReadAccessProxy;
34template <
typename T>
class OwningReadAwaiter;
72 this->move_exception_sink_from(other);
82 this->unregister_exception_sink(
false);
83 reader_ = std::move(other.reader_);
84 this->move_exception_sink_from(other);
90 ~ReadBuffer() noexcept { this->unregister_exception_sink(
true); }
94 NodeInfo const* node()
const {
return reader_.node(); }
101 ReadMaybeAwaiter<T const&>
maybe() &;
105 ReadMaybeAwaiter<T>
maybe() &&;
110 ReadOrCancelAwaiter<T const&>
or_cancel() &;
119 [[nodiscard]]
bool await_ready() const noexcept {
return reader_.ready(); }
125 TRACE_MODULE(ASYNC,
"ReadBuffer::await_suspend()",
this, t.coroutine_handle());
126 reader_.suspend(std::move(t));
131 [[nodiscard]] T
const&
await_resume() const& {
return reader_.data(); }
143 void release() noexcept { reader_.release(); }
154 void wait()
const { this->reader_.wait(); }
163 [[nodiscard]] T
const&
get_wait()
const {
return reader_.get_wait(); }
171 auto operator co_await() &
noexcept ->
ReadBuffer& {
return *
this; }
172 auto operator co_await()
const&
noexcept ->
ReadBuffer const& {
return *
this; }
192 void copy_exception_sink_from(
ReadBuffer const& other)
194 if (other.exception_sink_.
owner)
203 void move_exception_sink_from(ReadBuffer& other)
noexcept
205 if (!other.exception_sink_.
owner)
return;
206 auto* owner = other.exception_sink_.
owner;
207 auto epoch = std::move(other.exception_sink_.
epoch);
208 bool const explicit_sink = other.exception_sink_.
explicit_sink;
209 owner->unregister_exception_sink(other.exception_sink_,
false);
210 owner->register_exception_sink(exception_sink_, std::move(epoch), explicit_sink);
215 void unregister_exception_sink(
bool from_destructor)
noexcept
217 if (!exception_sink_.
owner)
return;
221 EpochContextReader<T> reader_;
222 mutable TaskPromiseBase::ExceptionSinkNode exception_sink_{};
247 [[nodiscard]] T const&
get()
const {
return this->reader_.data(); }
249 operator T
const&()
const {
return this->
get(); }
263 void release() noexcept { this->reader_.release(); }
289 [[nodiscard]]
bool await_ready() const noexcept {
return this->reader_.ready(); }
293 NodeInfo const* node()
const {
return reader_.node(); }
302 TRACE_MODULE(ASYNC,
"OwningReadAwaiter::await_suspend()",
this, t.coroutine_handle());
303 this->reader_.suspend(std::move(t));
330 [[nodiscard]]
bool await_ready() const noexcept {
return reader_.ready(); }
334 NodeInfo const* node()
const {
return reader_.node(); }
343 TRACE_MODULE(ASYNC,
"ReadBuffer::await_suspend()",
this, t.coroutine_handle());
344 this->reader_.suspend(std::move(t));
350 if (this->reader_.data_maybe() ==
nullptr)
352 this->reader_.release();
366 friend ReadBuffer<T>;
368 EpochContextReader<T> reader_;
382 [[nodiscard]]
bool await_ready() const noexcept {
return reader_.ready(); }
386 NodeInfo const* node()
const {
return reader_.node(); }
395 TRACE_MODULE(ASYNC,
"ReadBuffer::await_suspend()",
this, t.coroutine_handle());
396 reader_.suspend(std::move(t));
410 friend ReadBuffer<T>;
412 EpochContextReader<T>& reader_;
434 NodeInfo const* node()
const {
return reader_.node(); }
448 T
const* ptr = this->reader_.data_maybe();
451 this->reader_.release();
465 friend ReadBuffer<T>;
467 EpochContextReader<T> reader_;
489 NodeInfo const* node()
const {
return reader_.node(); }
503 T
const* ptr = reader_.data_maybe();
516 friend ReadBuffer<T>;
518 EpochContextReader<T>& reader_;
553#if UNI20_DEBUG_ASYNC_TASKS
555struct WriteProxyLifetimeState
557 std::atomic<bool> alive{
true};
571 [[nodiscard]]
bool await_ready() const noexcept {
return writer_->ready(); }
575 NodeInfo const* node()
const {
return writer_ ? writer_->node() :
nullptr; }
584 TRACE_MODULE(ASYNC,
"StorageAwaiter::await_suspend()",
this, t.coroutine_handle());
585 writer_->suspend(std::move(t));
593 return writer_->storage();
600 return writer_->epoch_context_shared();
617 [[nodiscard]]
bool await_ready() const noexcept {
return writer_->ready(); }
621 NodeInfo const* node()
const {
return writer_ ? writer_->node() :
nullptr; }
630 TRACE_MODULE(ASYNC,
"TakeAwaiter::await_suspend()",
this, t.coroutine_handle());
631 writer_->suspend(std::move(t));
639 return writer_->storage().take();
646 return writer_->epoch_context_shared();
663 [[nodiscard]]
bool await_ready() const noexcept {
return writer_->ready(); }
667 NodeInfo const* node()
const {
return writer_ ? writer_->node() :
nullptr; }
676 TRACE_MODULE(ASYNC,
"TakeReleaseAwaiter::await_suspend()",
this, t.coroutine_handle());
677 writer_->suspend(std::move(t));
685 T
value = writer_->storage().take();
694 return writer_->epoch_context_shared();
728 T
take() {
return writer_.storage().take(); }
740 void release() noexcept { writer_.release(); }
764 [[nodiscard]]
bool await_ready() const noexcept {
return writer_.ready(); }
768 NodeInfo const* node()
const {
return writer_.node(); }
777 TRACE_MODULE(ASYNC,
"OwningStorageAwaiter::await_suspend()",
this, t.coroutine_handle());
778 writer_.suspend(std::move(t));
793 return writer_.epoch_context_shared();
810 [[nodiscard]]
bool await_ready() const noexcept {
return writer_.ready(); }
814 NodeInfo const* node()
const {
return writer_.node(); }
823 TRACE_MODULE(ASYNC,
"OwningTakeAwaiter::await_suspend()",
this, t.coroutine_handle());
824 writer_.suspend(std::move(t));
832 T
value = writer_.storage().take();
841 return writer_.epoch_context_shared();
862 using element_type = std::conditional_t<is_async_alias_v<T>, T
const&, T&>;
871 this->invalidate_proxy_state();
872 this->unregister_exception_sink(
true);
882 this->move_exception_sink_from(other);
883 other.invalidate_proxy_state();
893 this->invalidate_proxy_state();
894 this->unregister_exception_sink(
false);
895 writer_ = std::move(other.writer_);
896 this->move_exception_sink_from(other);
897 this->reset_proxy_state();
898 other.invalidate_proxy_state();
904 NodeInfo const* node()
const {
return writer_.node(); }
911 [[nodiscard]]
bool await_ready() const noexcept {
return writer_.ready(); }
917 TRACE_MODULE(ASYNC,
"WriteBuffer::await_suspend()",
this, t.coroutine_handle());
918 writer_.suspend(std::move(t));
927#
if UNI20_DEBUG_ASYNC_TASKS
941#
if UNI20_DEBUG_ASYNC_TASKS
959 this->invalidate_proxy_state();
967 this->invalidate_proxy_state();
968 return std::move(*
this);
975 this->invalidate_proxy_state();
976 return std::move(*
this);
983 template <
typename... Args>
984 requires(!is_async_alias_v<T> && std::constructible_from<T, Args...>)
987 DEBUG_CHECK(writer_.ready(),
"WriteBuffer must be immediately writable");
988 writer_.emplace(std::forward<Args>(args)...);
989 return writer_.data();
995 requires(!is_async_alias_v<T>)
1003 requires(!is_async_alias_v<T>)
1005 this->invalidate_proxy_state();
1012 requires(!is_async_alias_v<T>)
1014 this->invalidate_proxy_state();
1021 requires(!is_async_alias_v<T>)
1023 this->invalidate_proxy_state();
1030 requires(!is_async_alias_v<T>)
1038 requires(!is_async_alias_v<T>)
1040 this->invalidate_proxy_state();
1059 requires(!is_async_alias_v<T>)
1061 return writer_.move_from_wait();
1067 template <
typename U>
1068 requires(!is_async_alias_v<T> || detail::async_alias_assignment_source<T, U>)
1077 template <
typename U>
1079 requires((!is_async_alias_v<T> && std::assignable_from<T&, U &&>) || detail::async_alias_assignable_from<T, U &&>)
1081 DEBUG_CHECK(writer_.ready(),
"WriteBuffer must be immediately writable");
1082 if constexpr (is_async_alias_v<T>)
1083 detail::assign_async_alias(writer_.data(), std::forward<U>(val));
1085 writer_.data() = std::forward<U>(val);
1091 template <
typename U>
1093 requires(!is_async_alias_v<T> && std::assignable_from<T&, U &&>)
1095 DEBUG_CHECK(writer_.ready(),
"WriteBuffer must be immediately writable");
1096 writer_.data() = std::move(val);
1106 template <
typename U>
1107 requires(!is_async_alias_v<T>)
1110 async_move(std::move(*
this), std::move(val));
1118 auto operator co_await()
const&
noexcept ->
WriteBuffer const& {
return *
this; }
1123 this->invalidate_proxy_state();
1130 void move_exception_sink_from(
WriteBuffer& other)
noexcept
1132 if (!other.exception_sink_.
owner)
return;
1133 auto* owner = other.exception_sink_.
owner;
1134 auto epoch = std::move(other.exception_sink_.
epoch);
1135 bool const explicit_sink = other.exception_sink_.
explicit_sink;
1136 owner->unregister_exception_sink(other.exception_sink_,
false);
1137 owner->register_exception_sink(exception_sink_, std::move(epoch), explicit_sink);
1142 void unregister_exception_sink(
bool from_destructor)
noexcept
1144 if (!exception_sink_.
owner)
return;
1149 void invalidate_proxy_state() noexcept
1151#if UNI20_DEBUG_ASYNC_TASKS
1152 if (proxy_state_) proxy_state_->alive.store(
false, std::memory_order_release);
1157 void reset_proxy_state() noexcept
1159#if UNI20_DEBUG_ASYNC_TASKS
1160 proxy_state_ = std::make_shared<WriteProxyLifetimeState>();
1164 EpochContextWriter<T> writer_;
1165 mutable TaskPromiseBase::ExceptionSinkNode exception_sink_{};
1166#if UNI20_DEBUG_ASYNC_TASKS
1167 std::shared_ptr<WriteProxyLifetimeState> proxy_state_{std::make_shared<WriteProxyLifetimeState>()};
1183 promise->ReadDependencies.push_back(x.node());
1195 promise->WriteDependencies.push_back(x.node());
1200template <
typename T>
class Defer;
1203template <
typename B>
1205 requires(B& buffer, TaskPromiseBase& promise) { buffer.register_exception_sink(promise,
true); };
1231 std::apply([&](
auto*... buffers) { (buffers->register_exception_sink(promise,
true), ...); }, buffers_);
1235 std::tuple<Buffers*...> buffers_;
1250template <
typename T,
typename U>
1251concept write_proxy_assignable_source = std::constructible_from<T, U&&> && std::is_assignable_v<T&, U&&>;
1254template <
typename T,
typename U>
1255 requires write_proxy_assignable_source<T, U>
1256void assign_write_proxy_value(EpochContextWriter<T>& writer, U&& source)
1258 if (writer.storage().constructed())
1259 writer.data() = std::forward<U>(source);
1261 writer.emplace(std::forward<U>(source));
1284 template <typename U>
1287 detail::async_alias_assignable_from<T, U &&>)
1290 if constexpr (is_async_alias_v<T>)
1291 detail::assign_async_alias(this->writer().data(), std::forward<U>(u));
1293 detail::assign_write_proxy_value(this->writer(), std::forward<U>(u));
1301 template <
typename... Args>
1302 requires(!is_async_alias_v<T> && std::constructible_from<T, Args...>)
1305 return this->writer().emplace(std::forward<Args>(args)...);
1312 template <
typename U>
1313 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value += std::forward<U>(x); }
1316 auto& storage = this->writer().storage();
1317 if (storage.constructed())
1319 this->
get() += std::forward<U>(x);
1321 else if constexpr (std::constructible_from<T, U&&>)
1323 storage.emplace(std::forward<U>(x));
1327 this->
get() += std::forward<U>(x);
1336 template <
typename U>
1337 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value -= std::forward<U>(x); }
1340 auto& storage = this->writer().storage();
1341 if (storage.constructed())
1343 this->
get() -= std::forward<U>(x);
1345 else if constexpr (
requires { -std::declval<U&&>(); } &&
1346 std::constructible_from<T,
decltype(-std::declval<U&&>())>)
1348 auto neg = -std::forward<U>(x);
1349 storage.emplace(std::move(neg));
1353 this->
get() -= std::forward<U>(x);
1362 template <
typename U>
1363 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value *= std::forward<U>(x); }
1366 this->
get() *= std::forward<U>(x);
1374 template <
typename U>
1375 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value /= std::forward<U>(x); }
1378 this->
get() /= std::forward<U>(x);
1385 requires(!is_async_alias_v<T>)
1387 return this->writer().storage().take();
1393 requires(!is_async_alias_v<T>)
1403#if UNI20_DEBUG_ASYNC_TASKS
1404 if (
auto state = proxy_state_.lock(); state)
1406 state->alive.store(
false, std::memory_order_release);
1421 return this->writer().data();
1426 [[nodiscard]] T
const&
get() const
1429 return this->writer().data();
1433 requires(!is_async_alias_v<T>)
1438 operator T
const&()
const
1439 requires(is_async_alias_v<T>)
1447 return std::addressof(this->
get());
1453 return std::addressof(this->
get());
1459#if UNI20_DEBUG_ASYNC_TASKS
1463#
if UNI20_DEBUG_ASYNC_TASKS
1465 std::shared_ptr<WriteProxyLifetimeState> proxy_state
1469#if UNI20_DEBUG_ASYNC_TASKS
1471 proxy_state_(std::move(proxy_state))
1479#if UNI20_DEBUG_ASYNC_TASKS
1480 auto state = proxy_state_.lock();
1481 DEBUG_CHECK(state && state->alive.load(std::memory_order_acquire),
1482 "WriteAccessProxy used after WriteBuffer moved, released, or destroyed");
1484 DEBUG_CHECK(writer_,
"WriteAccessProxy has no writer");
1491#if UNI20_DEBUG_ASYNC_TASKS
1492 std::weak_ptr<WriteProxyLifetimeState> proxy_state_;
1514 template <typename U>
1517 detail::async_alias_assignable_from<T, U &&>)
1520 if constexpr (is_async_alias_v<T>)
1521 detail::assign_async_alias(writer_.data(), std::forward<U>(u));
1523 detail::assign_write_proxy_value(writer_, std::forward<U>(u));
1531 template <
typename... Args>
1532 requires(!is_async_alias_v<T> && std::constructible_from<T, Args...>)
1535 return writer_.emplace(std::forward<Args>(args)...);
1542 template <
typename U>
1543 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value += std::forward<U>(x); }
1546 auto& storage = writer_.storage();
1547 if (storage.constructed())
1549 this->
get() += std::forward<U>(x);
1551 else if constexpr (std::constructible_from<T, U&&>)
1553 storage.emplace(std::forward<U>(x));
1557 this->
get() += std::forward<U>(x);
1566 template <
typename U>
1567 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value -= std::forward<U>(x); }
1570 auto& storage = writer_.storage();
1571 if (storage.constructed())
1573 this->
get() -= std::forward<U>(x);
1575 else if constexpr (
requires { -std::declval<U&&>(); } &&
1576 std::constructible_from<T,
decltype(-std::declval<U&&>())>)
1578 auto neg = -std::forward<U>(x);
1579 storage.emplace(std::move(neg));
1583 this->
get() -= std::forward<U>(x);
1592 template <
typename U>
1593 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value *= std::forward<U>(x); }
1596 this->
get() *= std::forward<U>(x);
1604 template <
typename U>
1605 requires(!is_async_alias_v<T>) &&
requires(T&
value, U&& x) {
value /= std::forward<U>(x); }
1608 this->
get() /= std::forward<U>(x);
1615 requires(!is_async_alias_v<T>)
1617 return writer_.data();
1621 T
const&
get()
const {
return writer_.data(); }
1626 requires(!is_async_alias_v<T>)
1628 return writer_.storage().take();
1634 requires(!is_async_alias_v<T>)
1645 requires(!is_async_alias_v<T>)
1649 operator T
const&()
const {
return this->
get(); }
1652 requires(!is_async_alias_v<T>)
1654 return std::addressof(this->
get());
1678 [[nodiscard]]
bool await_ready() const noexcept {
return writer_.ready(); }
1682 NodeInfo const* node()
const {
return writer_.node(); }
1691 TRACE_MODULE(ASYNC,
"OwningWriteAwaiter::await_suspend()",
this, task.coroutine_handle());
1692 writer_.suspend(std::move(task));
1707 return writer_.epoch_context_shared();
1733 template <typename U>
1736 void operator=(U&& u)
Promise-neutral coroutine task ownership and the public AsyncTask type.
Defines shared and concrete task coroutine promises.
Payload classification and write-through customization for asynchronous values.
Move-only promise-neutral ownership claim for a Uni20 coroutine.
Definition async_task.hpp:103
RAII handle representing the writer of a value in an EpochContext.
Definition epoch_context.hpp:874
RAII-scoped representation of a writer’s participation in an epoch.
Definition epoch_context.hpp:1048
void resume() const noexcept
Definition epoch_context.hpp:1121
Scheduler interface for initial AsyncTask submission and host-side progress.
Definition scheduler.hpp:89
Records node information for DAG/debugging visualization.
Definition async_node.hpp:171
Owning proxy returned by co_await read_buffer.transfer().
Definition buffers.hpp:235
T const & get() const
Access the referenced value.
Definition buffers.hpp:247
OwningReadAccessProxy(OwningReadAccessProxy &&) noexcept=default
T const * operator->() const
Definition buffers.hpp:251
T get_release()
Copy the value and release the read epoch in one call.
Definition buffers.hpp:255
OwningReadAccessProxy & operator=(OwningReadAccessProxy const &)=delete
OwningReadAccessProxy(OwningReadAccessProxy const &)=delete
void release() noexcept
Release the read epoch held by this proxy.
Definition buffers.hpp:263
T value_type
Definition buffers.hpp:237
OwningReadAccessProxy()=delete
Awaiter that transfers a read handle into an owning read proxy.
Definition buffers.hpp:279
void await_suspend(BasicTask &&t) noexcept
Suspend until the read epoch becomes available.
Definition buffers.hpp:300
T value_type
Definition buffers.hpp:281
OwningReadAwaiter(EpochContextReader< T > &&reader)
Construct from an owning epoch reader.
Definition buffers.hpp:285
OwningReadAccessProxy< T > await_resume()
Resume and transfer reader ownership to an owning read proxy.
Definition buffers.hpp:308
bool await_ready() const noexcept
Reports whether the read epoch is immediately ready.
Definition buffers.hpp:289
Owning proxy providing access to writer storage.
Definition buffers.hpp:703
shared_storage< T > * operator->()
Definition buffers.hpp:723
shared_storage< T > const * operator->() const
Definition buffers.hpp:724
T take()
Move the stored value out of writer storage.
Definition buffers.hpp:728
void release() noexcept
Release the writer epoch held by this proxy.
Definition buffers.hpp:740
OwningStorageAccessProxy()=delete
T take_release()
Move the stored value out and release the writer epoch.
Definition buffers.hpp:732
shared_storage< T > & get()
Returns mutable access to the underlying shared storage.
Definition buffers.hpp:715
shared_storage< T > const & get() const
Returns const access to the underlying shared storage.
Definition buffers.hpp:718
OwningStorageAccessProxy(OwningStorageAccessProxy &&) noexcept=default
OwningStorageAccessProxy & operator=(OwningStorageAccessProxy const &)=delete
OwningStorageAccessProxy(OwningStorageAccessProxy const &)=delete
Awaiter that yields an owning storage-access proxy.
Definition buffers.hpp:754
OwningStorageAccessProxy< T > await_resume()
Resume and transfer writer ownership to a storage proxy.
Definition buffers.hpp:783
void await_suspend(BasicTask &&t) noexcept
Suspend until the writer epoch becomes writable.
Definition buffers.hpp:775
bool await_ready() const noexcept
Reports whether the writer epoch is immediately writable.
Definition buffers.hpp:764
OwningStorageAwaiter(EpochContextWriter< T > &&writer)
Construct from an owning writer.
Definition buffers.hpp:760
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:791
Awaiter that takes and releases a value from an owning writer.
Definition buffers.hpp:802
bool await_ready() const noexcept
Reports whether the writer epoch is immediately writable.
Definition buffers.hpp:810
T await_resume()
Resume, move out the value, and release the writer epoch.
Definition buffers.hpp:829
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:839
OwningTakeAwaiter(EpochContextWriter< T > &&writer)
Construct from an owning writer.
Definition buffers.hpp:806
void await_suspend(BasicTask &&t) noexcept
Suspend until the writer epoch becomes writable.
Definition buffers.hpp:821
Owning proxy returned by co_await write_buffer.transfer().
Definition buffers.hpp:1498
T * operator->()
Definition buffers.hpp:1651
OwningWriteAccessProxy & operator*=(U &&x)
In-place *= update.
Definition buffers.hpp:1594
OwningWriteAccessProxy & operator-=(U &&x)
In-place -= update; emplaces negated value when unconstructed.
Definition buffers.hpp:1568
OwningWriteAccessProxy()=delete
T & emplace(Args &&... args)
Construct or replace the underlying value in place.
Definition buffers.hpp:1533
T const * operator->() const
Definition buffers.hpp:1656
T take()
Move out the stored value.
Definition buffers.hpp:1625
OwningWriteAccessProxy(OwningWriteAccessProxy const &)=delete
T take_release()
Move out the value and release the writer epoch.
Definition buffers.hpp:1633
T & get()
Access mutable stored value.
Definition buffers.hpp:1614
OwningWriteAccessProxy & operator+=(U &&x)
In-place += update; emplaces when storage is unconstructed.
Definition buffers.hpp:1544
T const & get() const
Access const stored value.
Definition buffers.hpp:1621
T value_type
Definition buffers.hpp:1500
OwningWriteAccessProxy(OwningWriteAccessProxy &&) noexcept=default
OwningWriteAccessProxy & operator/=(U &&x)
In-place /= update.
Definition buffers.hpp:1606
OwningWriteAccessProxy & operator=(OwningWriteAccessProxy const &)=delete
void release() noexcept
Release the writer epoch held by this proxy.
Definition buffers.hpp:1642
Awaiter that transfers a writer handle into an owning write proxy.
Definition buffers.hpp:1670
OwningWriteAwaiter(EpochContextWriter< T > &&writer)
Construct from an owning writer.
Definition buffers.hpp:1674
bool await_ready() const noexcept
Reports whether the writer epoch is immediately writable.
Definition buffers.hpp:1678
void await_suspend(BasicTask &&task) noexcept
Suspend until the writer epoch becomes writable.
Definition buffers.hpp:1689
OwningWriteAccessProxy< T > await_resume()
Resume and transfer writer ownership to an owning write proxy.
Definition buffers.hpp:1697
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:1705
Awaiter that registers explicit exception sinks and then resumes immediately.
Definition buffers.hpp:1209
PropagateExceptionsAwaiter(Buffers &... buffers)
Construct from references to sink buffers.
Definition buffers.hpp:1213
void register_exception_sinks(TaskPromiseBase &promise) const
Register all configured buffers as explicit exception sinks.
Definition buffers.hpp:1229
BasicTask await_suspend(BasicTask &&task) noexcept
Pass through the currently-running task unchanged.
Definition buffers.hpp:1222
void await_resume() noexcept
No-op resume hook.
Definition buffers.hpp:1225
bool await_ready() const noexcept
Always ready; no suspension required.
Definition buffers.hpp:1217
RAII handle for reading the value from an Async container at a given epoch.
Definition buffers.hpp:53
void await_suspend(BasicTask &&t) noexcept
Suspend this coroutine and enqueue for resumption.
Definition buffers.hpp:123
ReadMaybeAwaiter< T const & > maybe() &
Returns a ReadMaybeAwaiter.
Definition buffers.hpp:521
void release() noexcept
Manually release the epoch reader before awaitable destruction.
Definition buffers.hpp:143
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:179
T value_type
Definition buffers.hpp:55
ReadBuffer && transfer() &&noexcept
Transfer this read buffer into the owning-await path.
Definition buffers.hpp:151
ReadBuffer && transfer() &noexcept
Transfer this read buffer into the owning-await path.
Definition buffers.hpp:147
void register_exception_sink(TaskPromiseBase &promise, bool explicit_sink) const
Register this buffer as an exception sink with a promise.
Definition buffers.hpp:184
T const & get_wait(IAsyncScheduler &sched) const
Block using an explicit scheduler until the read value is available.
Definition buffers.hpp:168
ReadBuffer(ReadBuffer &&other) noexcept
Move constructor.
Definition buffers.hpp:70
T const & get_wait() const
Block until the read value is available.
Definition buffers.hpp:163
ReadBuffer(EpochContextReader< T > reader)
Construct a read buffer tied to a reader context.
Definition buffers.hpp:59
ReadOrCancelAwaiter< T const & > or_cancel() &
Returns a ReadOrCancelAwaiter.
Definition buffers.hpp:531
void wait() const
Block until the read value is available.
Definition buffers.hpp:154
bool await_ready() const noexcept
Check if the value is already ready to be read.
Definition buffers.hpp:119
void wait(IAsyncScheduler &sched) const
Block using an explicit scheduler until the read value is available.
Definition buffers.hpp:158
ReadBuffer & operator=(ReadBuffer &&other) noexcept
Move assignment.
Definition buffers.hpp:78
ReadBuffer & operator=(ReadBuffer const &)=delete
ReadBuffer(ReadBuffer const &other)
Copy constructor; duplicates read handle and exception sink registration.
Definition buffers.hpp:63
T const & await_resume() const &
Resume execution and return the stored value.
Definition buffers.hpp:131
~ReadBuffer() noexcept
Destructor unregisters any attached exception sink.
Definition buffers.hpp:90
T const * value_type
Definition buffers.hpp:375
value_type await_resume()
Resume execution and return a pointer to stored value, or nullptr.
Definition buffers.hpp:400
void await_suspend(BasicTask &&t) noexcept
Suspend this coroutine and enqueue for resumption.
Definition buffers.hpp:393
ReadMaybeAwaiter(ReadMaybeAwaiter &&)=default
Move constructor.
bool await_ready() const noexcept
Check if the value is already ready to be read.
Definition buffers.hpp:382
Awaiter returning an optional owning read proxy.
Definition buffers.hpp:321
ReadMaybeAwaiter(ReadMaybeAwaiter &&)=default
Move constructor.
bool await_ready() const noexcept
Check if the value is already ready to be read.
Definition buffers.hpp:330
void await_suspend(BasicTask &&t) noexcept
Suspend this coroutine and enqueue for resumption.
Definition buffers.hpp:341
value_type await_resume()
Resume execution and return an optional owning read proxy.
Definition buffers.hpp:348
std::optional< OwningReadAccessProxy< T > > value_type
Definition buffers.hpp:323
ReadOrCancelAwaiter(ReadOrCancelAwaiter &&)=default
Move constructor.
void await_suspend(BasicTask &&t) noexcept
Suspend this coroutine and enqueue for resumption.
Definition buffers.hpp:496
T const & await_resume()
Resume execution and return a borrowed reference to the stored value.
Definition buffers.hpp:501
bool await_ready() const noexcept
Check if the value is already ready to be read.
Definition buffers.hpp:481
T value_type
Definition buffers.hpp:474
Awaiter returning owning read access or throwing task_cancelled.
Definition buffers.hpp:417
void await_suspend(BasicTask &&t) noexcept
Suspend this coroutine and enqueue for resumption.
Definition buffers.hpp:441
bool await_ready() const noexcept
Check if the value is already ready to be read.
Definition buffers.hpp:426
OwningReadAccessProxy< T > value_type
Definition buffers.hpp:419
value_type await_resume()
Resume execution and return an owning read proxy.
Definition buffers.hpp:446
ReadOrCancelAwaiter(ReadOrCancelAwaiter &&)=default
Move constructor.
Awaiter returning direct access to a writer's shared storage object.
Definition buffers.hpp:563
void await_suspend(BasicTask &&t) noexcept
Suspend until the writer epoch becomes writable.
Definition buffers.hpp:582
StorageAwaiter(EpochContextWriter< T > *writer)
Construct from a non-owning writer pointer.
Definition buffers.hpp:567
bool await_ready() const noexcept
Reports whether the writer epoch is immediately writable.
Definition buffers.hpp:571
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:598
shared_storage< T > & await_resume()
Resume and return mutable access to shared storage.
Definition buffers.hpp:590
Awaiter that takes the writer value without releasing the writer epoch.
Definition buffers.hpp:609
bool await_ready() const noexcept
Reports whether the writer epoch is immediately writable.
Definition buffers.hpp:617
TakeAwaiter(EpochContextWriter< T > *writer)
Construct from a non-owning writer pointer.
Definition buffers.hpp:613
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:644
T await_resume()
Resume and move the stored value out of writer storage.
Definition buffers.hpp:636
void await_suspend(BasicTask &&t) noexcept
Suspend until the writer epoch becomes writable.
Definition buffers.hpp:628
Awaiter that takes a value and immediately releases the writer epoch.
Definition buffers.hpp:655
void await_suspend(BasicTask &&t) noexcept
Suspend until the writer epoch becomes writable.
Definition buffers.hpp:674
TakeReleaseAwaiter(EpochContextWriter< T > *writer)
Construct from a non-owning writer pointer.
Definition buffers.hpp:659
bool await_ready() const noexcept
Reports whether the writer epoch is immediately writable.
Definition buffers.hpp:663
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:692
T await_resume()
Resume, move out the value, and release the writer epoch.
Definition buffers.hpp:682
Shared non-polymorphic implementation for Uni20 task promises.
Definition async_task_promise.hpp:99
void register_exception_sink(ExceptionSinkNode &node, std::shared_ptr< EpochContext > epoch, bool explicit_sink)
Register one exception propagation sink with this promise.
Definition async_task_promise.hpp:239
void unregister_exception_sink(ExceptionSinkNode &node, bool from_destructor) noexcept
Unregister one exception propagation sink from this promise.
Definition async_task_promise.hpp:256
Non-owning proxy returned by co_await on an lvalue WriteBuffer<T>.
Definition buffers.hpp:1268
WriteAccessProxy(WriteAccessProxy &&) noexcept=default
void release() noexcept
Release the writer epoch held by this proxy.
Definition buffers.hpp:1401
WriteAccessProxy()=delete
WriteAccessProxy & operator*=(U &&x)
In-place *= update.
Definition buffers.hpp:1364
T value_type
Definition buffers.hpp:1270
T const * operator->() const
Definition buffers.hpp:1450
T & get() const
Access an independent stored value mutably.
Definition buffers.hpp:1418
T & emplace(Args &&... args)
Construct or replace the underlying value in place.
Definition buffers.hpp:1303
WriteAccessProxy & operator-=(U &&x)
In-place -= update; emplaces negated value when unconstructed.
Definition buffers.hpp:1338
WriteAccessProxy & operator+=(U &&x)
In-place += update; emplaces when storage is unconstructed.
Definition buffers.hpp:1314
T take()
Move out the stored value.
Definition buffers.hpp:1384
T * operator->() const
Definition buffers.hpp:1444
WriteAccessProxy(WriteAccessProxy const &) noexcept=default
WriteAccessProxy & operator/=(U &&x)
In-place /= update.
Definition buffers.hpp:1376
WriteAccessProxy & operator=(WriteAccessProxy const &)=delete
T const & get() const
Inspect an async alias descriptor without permitting retargeting.
Definition buffers.hpp:1426
T take_release()
Move out the value and release the writer epoch.
Definition buffers.hpp:1392
Assignment-only proxy returned by WriteBuffer::write().
Definition buffers.hpp:1720
WriteAssignProxy(WriteAssignProxy const &)=delete
T value_type
Definition buffers.hpp:1722
WriteAssignProxy & operator=(WriteAssignProxy const &)=delete
WriteAssignProxy()=delete
WriteAssignProxy(WriteAssignProxy &&) noexcept=default
Exclusive mutable-access buffer for one Async<T> epoch.
Definition buffers.hpp:859
void write_move_assert(U &&val)
Move-assign immediately when the writer is known to be ready.
Definition buffers.hpp:1092
OwningWriteAccessProxy< T > await_resume() &&
Resume and return an owning mutable write proxy.
Definition buffers.hpp:950
bool await_ready() const noexcept
Reports whether the writer epoch is immediately writable.
Definition buffers.hpp:911
auto take() &&-> OwningTakeAwaiter< T > requires(!is_async_alias_v< T >)
Awaiter that takes the stored value from an rvalue buffer.
Definition buffers.hpp:1002
void register_exception_sink(TaskPromiseBase &promise, bool explicit_sink) const
Register this buffer as an exception sink with a promise.
Definition buffers.hpp:1051
auto take_release() &&-> OwningTakeAwaiter< T > requires(!is_async_alias_v< T >)
Awaiter that takes the value and releases the writer epoch from an rvalue buffer.
Definition buffers.hpp:1020
T move_from_wait()
Wait for writability and move out the contained value.
Definition buffers.hpp:1058
T value_type
Definition buffers.hpp:861
std::shared_ptr< EpochContext > epoch_context_shared() const noexcept
Returns the epoch context used for exception propagation.
Definition buffers.hpp:1046
T & emplace_assert(Args &&... args)
Construct the destination value in-place when immediately writable.
Definition buffers.hpp:985
WriteAssignProxy< T > write()
Build an assignment-only proxy that consumes this writer.
Definition buffers.hpp:1757
auto storage() &&-> OwningStorageAwaiter< T > requires(!is_async_alias_v< T >)
Awaiter yielding owning access to writer shared storage.
Definition buffers.hpp:1037
auto storage() &
Awaiter yielding direct access to writer shared storage.
Definition buffers.hpp:1029
WriteBuffer && transfer() &&noexcept
Transfer this write buffer into the owning-await path.
Definition buffers.hpp:973
void release() noexcept
Release the writer epoch held by this buffer.
Definition buffers.hpp:957
WriteAccessProxy< T > await_resume() const &
Resume and return a non-owning mutable write proxy.
Definition buffers.hpp:936
void write(U &&val)
Schedule assignment into this write buffer.
Definition buffers.hpp:1069
auto take() &
Awaiter that takes the stored value.
Definition buffers.hpp:994
WriteBuffer & operator=(WriteBuffer &&other) noexcept
Move assignment.
Definition buffers.hpp:889
std::conditional_t< is_async_alias_v< T >, T const &, T & > element_type
Definition buffers.hpp:862
WriteAccessProxy< T > await_resume() &
Resume and return a non-owning mutable write proxy.
Definition buffers.hpp:923
void write_move(U &&val)
Schedule move-assignment into this write buffer.
Definition buffers.hpp:1108
WriteBuffer & operator=(WriteBuffer const &)=delete
WriteBuffer(WriteBuffer const &)=delete
auto take_release() &
Awaiter that takes the value and releases the writer epoch.
Definition buffers.hpp:1011
~WriteBuffer() noexcept
Destructor unregisters exception sink and invalidates debug proxy state.
Definition buffers.hpp:869
WriteBuffer && transfer() &noexcept
Transfer this write buffer into the owning-await path.
Definition buffers.hpp:965
void await_suspend(BasicTask &&t) noexcept
Suspend until the writer epoch becomes writable.
Definition buffers.hpp:915
WriteBuffer(EpochContextWriter< T > writer)
Construct a write buffer tied to a writer context.
Definition buffers.hpp:866
WriteBuffer(WriteBuffer &&other) noexcept
Move constructor.
Definition buffers.hpp:880
void write_assert(U &&val)
Assign immediately when the writer is known to be ready.
Definition buffers.hpp:1078
A lightweight, thread-safe, reference-counted storage for a single object.
Definition shared_storage.hpp:94
Raised when an AsyncTask is cancelled before completion.
Definition async_errors.hpp:44
Concept for buffers that can register explicit exception sinks.
Definition buffers.hpp:1204
locale_t value
Definition data_table.cpp:49
Manages one “generation” of write/read ordering in an Async<T>
void async_move(WriteBuffer< T > lhs, U &&rhs)
Definition async_ops.hpp:369
void async_assign(WriteBuffer< T > destination, U &&source)
Assign an awaitable value into an existing independent-value timeline.
Definition async_ops.hpp:310
This represents the reverse-mode adjoint for functions of complex variables, assuming a real-valued s...
Definition async/async.hpp:26
ReadBuffer< T > && release(ReadBuffer< T > &in)
Adaptor for transferring ReadBuffer ownership into an await expression.
Definition buffers.hpp:227
auto propagate_exceptions_to(Buffers &... buffers)
Register buffers that should receive unhandled coroutine exceptions.
Definition buffers.hpp:1241
constexpr bool is_async_alias_v
True when T is an owner-bound async alias descriptor.
Definition async_traits.hpp:53
void ProcessCoroutineArgument(TaskPromiseBase *promise, T const &value)
Process a coroutine argument for debug metadata (default no-op).
Definition async_task_promise.hpp:946
Reference-counted optional in-place storage used by async buffers.
TaskPromiseBase * owner
Definition async_task_promise.hpp:104
bool explicit_sink
Definition async_task_promise.hpp:108
std::shared_ptr< EpochContext > epoch
Definition async_task_promise.hpp:107
#define DEBUG_CHECK(cond,...)
Definition trace.hpp:608
#define TRACE_MODULE(m,...)
Definition trace.hpp:149