From 9bd438df6b545b7a77ac22903515dfeeb5cd60ef Mon Sep 17 00:00:00 2001 From: Alexander van der Grinten Date: Tue, 27 Jan 2026 22:13:33 +0100 Subject: [PATCH 1/2] post-ack: Add missing value_type --- include/async/post-ack.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/async/post-ack.hpp b/include/async/post-ack.hpp index f375272..fe1528d 100644 --- a/include/async/post-ack.hpp +++ b/include/async/post-ack.hpp @@ -115,6 +115,8 @@ struct post_ack_mechanism { }; struct [[nodiscard]] post_sender { + using value_type = void; + friend sender_awaiter operator co_await (post_sender sender) { return {std::move(sender)}; } From f310d930cdf14277aa9051c295ea1ccf111b39f2 Mon Sep 17 00:00:00 2001 From: Alexander van der Grinten Date: Thu, 29 Jan 2026 17:49:42 +0100 Subject: [PATCH 2/2] execution: Add get_env() CPO This can be used to obtain an environment object from a receiver. The environment object can be used to pass information from receivers to operations and similar. This mechanism is part of std::execution. --- include/async/algorithm.hpp | 24 ++++++++++++++++++++++++ include/async/cancellation.hpp | 4 ++++ include/async/execution.hpp | 19 +++++++++++++++++++ include/async/wait-group.hpp | 4 ++++ 4 files changed, 51 insertions(+) diff --git a/include/async/algorithm.hpp b/include/async/algorithm.hpp index 1e7710a..7a452c9 100644 --- a/include/async/algorithm.hpp +++ b/include/async/algorithm.hpp @@ -94,6 +94,10 @@ struct value_transform_receiver { } } + auto get_env() { + return execution::get_env(dr_); + } + private: Receiver dr_; // Downstream receiver. [[no_unique_address]] F f_; @@ -113,6 +117,10 @@ struct void_transform_receiver { } } + auto get_env() { + return execution::get_env(dr_); + } + private: Receiver dr_; // Downstream receiver. [[no_unique_address]] F f_; @@ -281,6 +289,10 @@ struct [[nodiscard]] repeat_while_operation { execution::set_value(s->dr_); } + auto get_env() { + return execution::get_env(self_->dr_); + } + private: repeat_while_operation *self_; }; @@ -359,6 +371,10 @@ struct race_and_cancel_operation, std::index_s execution::set_value(self_->r_); } + auto get_env() { + return execution::get_env(self_->r_); + } + private: race_and_cancel_operation *self_; }; @@ -595,6 +611,10 @@ struct [[nodiscard]] sequence_operation { execution::set_value(s->dr_, std::move(value)); } + auto get_env() { + return execution::get_env(self_->dr_); + } + private: sequence_operation *self_; }; @@ -657,6 +677,10 @@ struct when_all_operation { execution::set_value(self_->dr_); } + auto get_env() { + return execution::get_env(self_->dr_); + } + private: when_all_operation *self_; }; diff --git a/include/async/cancellation.hpp b/include/async/cancellation.hpp index 2052a5c..5fcc79e 100644 --- a/include/async/cancellation.hpp +++ b/include/async/cancellation.hpp @@ -387,6 +387,10 @@ struct with_cancel_cb_operation { self->complete_(); } + auto get_env() { + return execution::get_env(self->dr_); + } + with_cancel_cb_operation *self; }; static_assert(Receives); diff --git a/include/async/execution.hpp b/include/async/execution.hpp index 99596f0..e137839 100644 --- a/include/async/execution.hpp +++ b/include/async/execution.hpp @@ -111,6 +111,24 @@ struct set_value_cpo { } }; +template +concept get_env_member = requires(T &&obj) { + obj.get_env(); +}; + +struct empty_env { }; + +struct get_env_cpo { + template + auto operator() (T &&obj) { + if constexpr (get_env_member) { + return obj.get_env(); + } else { + return empty_env{}; + } + } +}; + } // namespace cpo_types namespace execution { @@ -121,6 +139,7 @@ namespace execution { inline cpo_types::start_cpo start; inline cpo_types::start_inline_cpo start_inline; inline cpo_types::set_value_cpo set_value; + inline cpo_types::get_env_cpo get_env; } } // namespace async diff --git a/include/async/wait-group.hpp b/include/async/wait-group.hpp index 10fe219..2a4fda9 100644 --- a/include/async/wait-group.hpp +++ b/include/async/wait-group.hpp @@ -197,6 +197,10 @@ struct [[nodiscard]] sender_ { std::forward(ts)... ); } + + auto get_env() { + return execution::get_env(op_.originalr_); + } }; execution::operation_t originalop_;