diff --git a/README.md b/README.md index 6ff6f784..12b78952 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception --> -[![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg)](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#the-beman-library-maturity-model)![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp26.svg)[![Coverage](https://coveralls.io/repos/github/bemanproject/execution/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/execution?branch=main)[![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/9nfa3rTTK) +[![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg)](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#the-beman-library-maturity-model)![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp26.svg)[![Coverage](https://coveralls.io/repos/github/bemanproject/execution/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/execution?branch=main)[![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/jeMEWGYbM) diff --git a/docs/implementation-status.md b/docs/implementation-status.md new file mode 100644 index 00000000..cc64333e --- /dev/null +++ b/docs/implementation-status.md @@ -0,0 +1,301 @@ +# Implementation Status + +Meaning of the status indicators (in order best to worst): + +- ❎: reviewed and not applicable (e.g. because a section doesn't provide something which would be reflected in code) +- ✅: reviewed and OK +- 🔴: reviewed and found incomplete +- 🚧: no or incomplete review + +The indicators come in groups of threes: +1. The item is implemented +2. The item is tested +3. The item is documented (for a somewhat loose definition of "documented": something is said in the [overview](https://github.com/bemanproject/execution/blob/main/docs/overview.md)) + +Each section containing subelements reflects the state of the "worst" element. + +# 🔴🔴🔴 [exec](https://wg21.link/exec) Execution control library +## 🚧✅✅ [exec.general](https://wg21.link/exec.general) General + +- 🚧❎❎ [MANDATE-NOTHROW(expr)](https://wg21.link/exec.general#5) ⇒ noexcept(expr) is `true` +- ✅✅✅ [movable-value<T>](https://wg21.link/exec.general#6): [`movable_value.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/movable_value.hpp) +- ✅✅✅ [MATCHING-SIG<F1, F2>](https://wg21.link/exec.general#7): [`matching_sig.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/matching_sig.hpp) +- ✅✅✅ [AS-EXCEPT-PTR(error)](https://wg21.link/exec.general#8): [`as_except_ptr.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/as_except_ptr.hpp) +- 🚧❎❎ [as-const(error)](https://wg21.link/exec.general#9): [std::as_const](https://wg21.link/utility.as.const)(error) + +## 🚧✅✅ [exec.queryable](https://wg21.link/exec.queryable) Query and queryables +### 🚧❎❎ [exec.queryable.general](https://wg21.link/exec.queryable.general) General +### 🚧✅✅ [exec.queryable.concept](https://wg21.link/exec.queryable.concept) Queryable concept + +- 🚧✅✅ [queryable<Q>](https://wg21.link/exec.queryable.concept#1): [`queryable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/queryable.hpp) + +## ❎❎❎ [exec.async.ops](https://wg21.link/exec.async.ops) Asynchronous operations +## ✅✅🔴 [execution.syn](https://wg21.link/execution.syn) Header `` synopsis + +- ✅✅🔴 [is_execution_policy<T>](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [is_execution_policy_v<T>](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [sequenced_policy<T>](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [parallel_policy<T>](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [parallel_unsequenced_policy<T>](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [unsequenced_policy<T>](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [seq](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [par](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [par_unseq](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅🔴 [unseq](https://wg21.link/execution.syn): [`execution_policy.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/execution_policy.hpp) +- ✅✅✅ [movable-value<T>](https://wg21.link/exec.general#6): [`movable_value.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/movable_value.hpp) +- ✅✅✅ [decays-to](https://wg21.link/execution.syn): [`decays_to.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/decays_to.hpp) +- ✅✅✅ [class-type](https://wg21.link/execution.syn): [`class_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/class_type.hpp) +- ✅✅✅ [queryable<Q>](https://wg21.link/exec.queryable.concept#1): [`queryable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/queryable.hpp) +- ✅✅✅ [single-sender-value_type<Sndr, Env...>](https://wg21.link/exec.queryable.concept#1): [`single_sender_value_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/single_sender_value_type.hpp) +- ✅✅✅ [single-sender<Sndr, Env...>](https://wg21.link/exec.queryable.concept#1): [`single_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/single_sender.hpp) + +## 🔴🔴🔴 [exec.queries](https://wg21.link/exec.queries) Queries +### ✅✅✅ [exec.queries.expos](https://wg21.link/exec.queries.expos) Query utilities + +- ✅✅✅ [TRY-QUERY(q, tag, a...)](https://wg21.link/exec.queries.expos#2): [`try_query.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/try_query.hpp) +- ✅✅✅ [HIDE-SCHED(q, tag, a...)](https://wg21.link/exec.queries.expos#3): [`hide_sched.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/hide_sched.hpp) + +### ✅✅✅ [exec.fwd.env](https://wg21.link/exec.fwd.env) `forwarding_query`: [`forwarding_query.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/forwarding_query.hpp) +### ✅✅✅ [exec.get.allocator](https://wg21.link/exec.get.allocator) `get_allocator`: [`get_allocator.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_allocator.hpp) +### ✅✅✅ [exec.get.stop.token](https://wg21.link/exec.get.stop.token) `get_stop_token`: [`get_stop_token.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_stop_token.hpp) +### ✅✅✅ [exec.get.env](https://wg21.link/exec.get.env) `execution::get_env`: [`get_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_env.hpp) +### ✅✅✅ [exec.get.domain](https://wg21.link/exec.get.domain) `execution::get_domain`: [`get_domain.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_domain.hpp) +### ✅✅✅ [exec.get.scheduler](https://wg21.link/exec.get.scheduler) `execution::get_scheduler`: [`get_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_scheduler.hpp) +### ✅✅✅ [exec.get.start.scheduler](https://wg21.link/exec.get.start.scheduler) `execution::get_start_scheduler`: [`get_start_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_start_scheduler.hpp) +### ✅✅✅ [exec.get.delegation.scheduler](https://wg21.link/exec.get.delegation.scheduler) `execution::get_delegation_scheduler`: [`get_delegation_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_delegation_scheduler.hpp) +### ✅✅✅ [exec.get.fwd.progress](https://wg21.link/exec.get.fwd.progress) `execution::get_forward_progress_guarantee` + +- ✅✅✅ [`forward_progress_guarantee`](https://wg21.link/exec.get.fwd.progress): [`get_forward_progress_guarantee.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_forward_progress_guarantee.hpp) +- ✅✅✅ [`get_forward_progress_guarantee`](https://wg21.link/exec.get.fwd.progress#2): [`get_forward_progress_guarantee.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_forward_progress_guarantee.hpp) + +### ✅✅✅ [exec.get.compl.sched](https://wg21.link/exec.get.compl.sched) `execution::get_completion_scheduler`: [`get_completion_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_completion_scheduler.hpp) + +- ❎ check [exec.get.compl.sched p6](https://wg21.link/exec.get.compl.sched#6) + +### ✅✅🔴 [exec.get.compl.domain](https://wg21.link/exec.get.compl.domain) `execution::get_completion_domain`: [`get_completion_domain.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_completion_domain.hpp) + +- ❎ check [exec.get.compl.domain p3](https://wg21.link/exec.get.compl.domain#3 + +### ✅🔴🔴 [exec.get.await.adapt](https://wg21.link/exec.get.await.adapt) `execution::get_await_completion_adaptor`: [`get_await_completion_adaptor.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_await_completion_adaptor.hpp) +## ✅🔴✅ [exec.sched](https://wg21.link/exec.sched) Schedulers + +- ✅✅✅ [`scheduler`](https://wg21.link/exec.sched#1): [`scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/scheduler.hpp) +- ✅🔴✅ [infallible-scheduler](https://wg21.link/exec.sched#8): [`infallible_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/infallible_scheduler.hpp) + +## 🔴🔴🔴 [exec.recv](https://wg21.link/exec.recv) Receivers +### 🔴🔴🔴 [exec.recv.concepts](https://wg21.link/exec.recv.concepts) Receiver concepts + +- ✅✅✅ [`receiver`](https://wg21.link/exec.recv.concepts#1): [`receiver.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/receiver.hpp) +- ✅✅✅ [valid-completion-for](https://wg21.link/exec.recv.concepts#1): [`valid_completion_for.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/valid_completion_for.hpp) +- ✅✅✅ [has-completion](https://wg21.link/exec.recv.concepts#1): [`has_completions.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/has_completions.hpp) +- ✅✅✅ [receiver-of](https://wg21.link/exec.recv.concepts#1): [`receiver_of.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/receiver_of.hpp) +- 🔴🔴🔴 [inlinable_receiver](https://wg21.link/exec.recv.concepts#4) + +### ✅✅✅ [exec.set.value](https://wg21.link/exec.set.value) `execution::set_value`: [`set_value.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/set_value.hpp) +### ✅✅✅ [exec.set.error](https://wg21.link/exec.set.error) `execution::set_error`: [`set_error.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/set_error.hpp) +### ✅✅✅ [exec.set.stopped](https://wg21.link/exec.set.stopped) `execution::set_stopped`: [`set_stopped.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/set_stopped.hpp) +## ✅✅✅ [exec.opstate](https://wg21.link/exec.opstate) Operation states +### ✅✅✅ [exec.opstate.general](https://wg21.link/exec.opstate.general) General: [`operation_state.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/operation_state.hpp) +### ✅✅✅ [exec.opstate.start](https://wg21.link/exec.opstate.start) `execution::start`: [`start.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/start.hpp) +## 🔴🔴🔴 [exec.snd](https://wg21.link/exec.snd) Senders +### ❎❎❎ [exec.snd.general](https://wg21.link/exec.snd.general) General +### 🔴🔴🔴 [exec.snd.expos](https://wg21.link/exec.snd.expos) Exposition-only entities + +- ✅✅✅ [exec.snd.expos p4](https://wg21.link/exec.snd.expos#4) FWD-ENV(env): [`fwd_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/fwd_env.hpp) +- ✅✅✅ [exec.snd.expos p4](https://wg21.link/exec.snd.expos#4) FWD-ENV-T(Env): [`fwd_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/fwd_env.hpp) +- ✅✅✅ [exec.snd.expos p5](https://wg21.link/exec.snd.expos#5) MAKE-ENV(q, v): [`make_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/make_env.hpp) +- ✅✅✅ [exec.snd.expos p6](https://wg21.link/exec.snd.expos#6) JOIN-ENV(ev1, ev2): [`join_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/join_env.hpp) +- ✅🔴✅ [exec.snd.expos p8](https://wg21.link/exec.snd.expos#8) COMMON-DOMAIN(domains...): [`common_domain.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/common_domain.hpp) +- ✅✅✅ [exec.snd.expos p9](https://wg21.link/exec.snd.expos#9) COMPL-DOMAIN(sndr, ev...): [`compl_domain.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/compl_domain.hpp) 🚨 the name appears to be unused! +- ✅✅✅ [exec.snd.expos p10](https://wg21.link/exec.snd.expos#10) SCHED-ENV(sch): [`sched_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sched_env.hpp) +- 🚧🚧🚧 [exec.snd.expos p11](https://wg21.link/exec.snd.expos#11) SET-VALUE(rcvr, expr): [`set_value.hpp](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/set_value.hpp), TRY-EVAL(expr): [`common.hpp](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/common.hpp), TRY-SET-VALUE(rcvr, expr) +- ✅✅✅ [exec.snd.expos p12](https://wg21.link/exec.snd.expos#12) query-with-default(tag, env, value): [`query_with_default.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/query_with_default.hpp) +- ✅🔴🔴 [exec.snd.expos p15](https://wg21.link/exec.snd.expos#15) emplace-from{fun}: [`emplace_from.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/emplace_from.hpp) +- ✅🔴🔴 [exec.snd.expos p12](https://wg21.link/exec.snd.expos#16) on-stop-request{stop_source}: [`on_stop_request.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/on_stop_request.hpp) +- ✅✅✅ [exec.snd.expos p17](https://wg21.link/exec.snd.expos#17) product-type{members...}: [`product_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/product_type.hpp) +- ✅✅✅ [exec.snd.expos p23](https://wg21.link/exec.snd.expos#23) valid-specialization<T, Args...>: [`valid_specialization.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/valid_specialization.hpp) +- ✅✅✅ [exec.snd.expos p24](https://wg21.link/exec.snd.expos#24) make-sender(tag, data = empty{}, child...): [`make_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/make_sender.hpp) +- ✅✅🔴 [exec.snd.expos p27](https://wg21.link/exec.snd.expos#27) state-type<Sndr, Rcvr<: [`state_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/state_type.hpp) env-type<Index, Sndr, Rcvr<: [`env_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/env_type.hpp) data-type<Sndr<: [`data_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/data_type.hpp) child-type<Sndr, I = 0<: [`child_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/child_type.hpp) indices-for<Sndr<: [`indices_for.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/indices_for.hpp) basic-state<Sndr<: [`basic_state.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/basic_state.hpp) +- ✅✅🔴 [exec.snd.expos p29](https://wg21.link/exec.snd.expos#29) basic-receiver<Sndr, Rcvr, Index>: [`basic_receiver.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/basic_receiver.hpp) +- ✅✅🔴 [exec.snd.expos p30](https://wg21.link/exec.snd.expos#30) connect-all{&op, sndr, indices}: [`connect_all.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/connect_all.hpp) +- ✅✅🔴 [exec.snd.expos p33](https://wg21.link/exec.snd.expos#33) basic-operation<Sndr, Rcvr>: [`basic_operation.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/basic_operation.hpp) +- ✅✅🔴 [exec.snd.expos p35](https://wg21.link/exec.snd.expos#35) default-impls: [`default_impls.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/default_impls.hpp) 🚨 verify check-types and impls-for members +- ✅✅🔴 [exec.snd.expos p43](https://wg21.link/exec.snd.expos#43) basic-sender<Tag, Data, Child...>: [`basic_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/basic_sender.hpp) +- 🔴🔴🔴 [exec.snd.expos p50](https://wg21.link/exec.snd.expos#50) overload-set<Funs...> +- 🔴🔴🔴 [exec.snd.expos p51](https://wg21.link/exec.snd.expos#51) not-a-sender +- 🔴🔴🔴 [exec.snd.expos p52](https://wg21.link/exec.snd.expos#52) not-a-scheduler +- 🔴🔴🔴 [exec.snd.expos p53](https://wg21.link/exec.snd.expos#53) decay-copyable-result-datums +- 🔴🔴🔴 [exec.snd.expos p54](https://wg21.link/exec.snd.expos#54) allocator-aware-forward(obj, env) +- ✅🔴🔴 [exec.snd.expos p56](https://wg21.link/exec.snd.expos#56) call-with-default(fn, value, args...): [`call_with_default.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/call_with_default.hpp) +- ✅✅🔴 [exec.snd.expos p59](https://wg21.link/exec.snd.expos#59) inline-attrs<T>: [`inline_attrs.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/inline_attrs.hpp) + +### 🔴🔴🔴 [exec.snd.concepts](https://wg21.link/exec.snd.concepts) Sender concepts + +- ✅🔴🔴 [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) is-constant<Value>: [`is_constant.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/is_constant.hpp) +- ✅✅🔴 [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) is-sender<Value>: [`is_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/is_sender.hpp) +- ✅✅🔴 [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) enable-sender<Value>: [`enable_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/enable_sender.hpp) +- 🔴🔴🔴 [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) is-dependent-sender-helper<Sndr> +- ✅✅✅ [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) sender<T>: [`sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sender.hpp) +- ✅✅✅ [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) sender_in<T, Env...>: [`sender_in.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sender_in.hpp) +- ✅✅✅ [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) dependent_sender<T, Env...>: [`sender_in.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sender_in.hpp) +- ✅✅✅ [exec.snd.concepts p1](https://wg21.link/exec.snd.concepts#1) sender_to<Sndr, Rcvr>: [`sender_to.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sender_to.hpp) +- 🔴🔴🔴 [exec.snd.concepts p5](https://wg21.link/exec.snd.concepts#5) value-signature<As...> +- 🔴🔴🔴 [exec.snd.concepts p5](https://wg21.link/exec.snd.concepts#5) sender-in-of-impl<Sndr, SetValue, Env...> +- 🔴🔴🔴 [exec.snd.concepts p5](https://wg21.link/exec.snd.concepts#5) sender-in-of<Sndr, Env, Values...> +- 🔴🔴🔴 [exec.snd.concepts p5](https://wg21.link/exec.snd.concepts#5) sender-of<Sndr, Values...> +- ✅✅✅ [exec.snd.concepts p6](https://wg21.link/exec.snd.concepts#6) tag_of_t<Sndr>: [`tag_of_t.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/tag_of_t.hpp) +- ✅✅✅ [exec.snd.concepts p7](https://wg21.link/exec.snd.concepts#7) sender-for<Sndr, tag>: [`sender_for.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sender_for.hpp) +- 🔴🔴🔴 [exec.snd.concepts p8](https://wg21.link/exec.snd.concepts#8) SET-VALUE-SIG(T) + +### ✅✅🔴 [exec.awaitable](https://wg21.link/exec.awaitable) Awaitable helpers + +- ✅✅🔴 [exec.awaitable p2](https://wg21.link/exec.awitable#2) GET-AWAITER(c, p): [`get_awaiter.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_awaiter.hpp) +- ✅✅🔴 [exec.awaitable p3](https://wg21.link/exec.awitable#3) await-suspend-result<T>: [`await_suspend_result.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/await_suspend_result.hpp) +- ✅✅🔴 [exec.awaitable p3](https://wg21.link/exec.awitable#3) is-awaiter<A, Promise...>: [`await_suspend_result.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/await_suspend_result.hpp) +- ✅✅🔴 [exec.awaitable p3](https://wg21.link/exec.awitable#3) is-awaitable<C, Promise...>: [`is_awaitable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/is_awaitable.hpp) +- ✅✅🔴 [exec.awaitable p5](https://wg21.link/exec.awitable#5) has-as-awaitable<T, Promise>: [`has_as_awaitable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/has_as_awaitable.hpp) +- ✅✅🔴 [exec.awaitable p5](https://wg21.link/exec.awitable#5) with-await-transform<Derived>: [`has_as_awaitable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/has_as_awaitable.hpp) +- ✅✅🔴 [exec.awaitable p6](https://wg21.link/exec.awitable#6) env-promise<Env>: [`env_promise.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/env_promise.hpp) + +### ✅✅🔴 [exec.domain.indeterminate](https://wg21.link/exec.domain.indeterminate) `execution::indeterminate_domain`: [`indeterminate_domain.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/indeterminate_domain.hpp) +### ✅✅🔴 [exec.domain.default](https://wg21.link/exec.domain.default) `execution::default_domain`: [`default_domain.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/default_domain.hpp) +### ✅✅🔴 [exec.snd.transform](https://wg21.link/exec.snd.transform) `exuection::transform_sender`: [`transform_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/transform_sender.hpp) +### ✅✅🔴 [exec.snd.apply](https://wg21.link/exec.snd.apply) `execution::apply_sender`: [`apply_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/apply_sender.hpp) +### ✅✅✅ [exec.getcomplsigs](https://wg21.link/exec.getcomplsigs) `execution::get_completion_signatures`: [`get_completion_signatures.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/get_completion_signatures.hpp) +### 🔴🔴🔴 [exec.connect](https://wg21.link/exec.connect) `execution::connect` + +- ✅✅✅ [exec.connect p2](https://wg21.link/exec.connect#2) connect(sndr, rcvr): [`connect.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/connect.hpp) +- ✅✅✅ [exec.connect p3](https://wg21.link/exec.connect#3) connect-awaitable-promise: [`operation_state_task.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/operation_state_task.hpp) +- ✅✅✅ [exec.connect p4](https://wg21.link/exec.connect#4) operation-state-task: [`operation_state_task.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/operation_state_task.hpp) +- ✅✅🔴 [exec.connect p5](https://wg21.link/exec.connect#5) await-result-type<DS, Promise>: [`await_result_type.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/await_result_type.hpp) +- ✅✅🔴 [exec.connect p5](https://wg21.link/exec.connect#5) suspend-complete(fun, as...): [`suspend_complete.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/suspend_complete.hpp) +- ✅✅🔴 [exec.connect p5](https://wg21.link/exec.connect#5) connect-awaitable(sndr, rcvr): [`connect_awaitable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/connect_awaitable.hpp) + +## ✅✅✅ [exec.factories](https://wg21.link/exec.factories) Sender factories +### ✅✅✅ [exec.schedule](https://wg21.link/exec.schedule) `execution::schedule`: [`schedule.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/schedule.hpp) +### ✅✅✅ [exec.just](https://wg21.link/exec.just) `execution::just`, `exuection::just_error`, `execution::just_stopped`: [`just.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/just.hpp) +### ✅✅✅ [exec.read.env](https://wg21.link/exec.read.env) `execution::read_env`: [`read_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/read_env.hpp) +## ✅🔴🔴 [exec.adapt](https://wg21.link/exec.adapt) Sender adaptors +### ✅🔴🔴 [exec.adapt.general](https://wg21.link/exec.adapt.general) General + +- 🚧 [exec.adapt.general p3.2](https://wg21.link/exec.adapt.general#3.2) verify single child env +- 🚧 [exec.adapt.general p3.3](https://wg21.link/exec.adapt.general#3.3) verify multi child env +- 🚧 [exec.adapt.general p3.4](https://wg21.link/exec.adapt.general#3.4) verify child's receiver's env +- 🚧 [exec.adapt.general p3.5](https://wg21.link/exec.adapt.general#3.5) sender non-dependent + +### ✅✅🔴 [exec.adapt.obj](https://wg21.link/exec.adapt.obj) Closure objects + +- 🚧 [exec.adapt.obj p1](https://wg21.link/exec.adapt.general#1) verify senders are pipeable +- 🚧 [exec.adapt.obj p1](https://wg21.link/exec.adapt.general#1) verify pipeable sender adaptor closure objects compose + +### ✅✅✅ [exec.write.env](https://wg21.link/exec.write.env) `execution::write_env`: [`write_env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/write_env.hpp) +### ✅✅✅ [exec.unstoppable](https://wg21.link/exec.unstoppable) `execution::unstoppable`: [`unstoppable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/unstoppable.hpp) +### ✅✅✅ [exec.starts.on](https://wg21.link/exec.starts.on) `execution::starts_on`: [`starts_on.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/starts_on.hpp) +### ✅✅✅ [exec.continues.on](https://wg21.link/exec.continues.on) `execution::continues_on`: [`continues_one.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/continues_one.hpp) +### ✅✅✅ [exec.schedule.from](https://wg21.link/exec.schedule.from) `execution::schedule_from`: [`schedule_from.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/schedule_from.hpp) +### ✅✅✅ [exec.on](https://wg21.link/exec.on) `execution::on`: [`on.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/on.hpp) +### ✅✅✅ [exec.then](https://wg21.link/exec.then) `execution::then`, `execution::upon_error`, `execution::upon_stopped`: [`then.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/then.hpp) + +- 🔴 [exec.then p5](https://wg21.link/exec.then#5) verify check-types + +### ✅✅✅ [exec.let](https://wg21.link/exec.let) `execution::let_value`, `execution::let_error`, `execution::let_stopped`: [`let.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/let.hpp) + +- 🔴 [exec.let p9](https://wg21.link/exec.let#9) verify check-types + +### ✅✅🔴 [exec.bulk](https://wg21.link/exec.bulk) `execution::bulk`, `execution::bulk_chunked`, and `execution::bulk_unchunked`: [`bulk.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/bulk.hpp) + +- 🔴 [exec.bulk p6](https://wg21.link/exec.let#6) verify check-types +- 🔴 [exec.bulk p8](https://wg21.link/exec.let#8) verify check-types + +### ✅✅✅ [exec.when.all](https://wg21.link/exec.when.all) `execution::when_all`: [`when_all.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/when_all.hpp) + +- 🔴 [exec.adapt.general p3.2](https://wg21.link/exec.adapt.general#3.2) verify single child env +- 🔴 [exec.when.all p9](https://wg21.link/exec.when.all#9) check use of count-of + +### ✅✅✅ [exec.into.variant](https://wg21.link/exec.into.variant) `execution::into_variant`: [`into_variant.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/into_variant.hpp) +### ✅✅🔴 [exec.stopped.opt](https://wg21.link/exec.stopped.opt) `execution::stopped_as_optional`: [`stopped_as_optional.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/stopped_as_optional.hpp) +### ✅✅🔴 [exec.stopped.err](https://wg21.link/exec.stopped.err) `execution::stopped_as_error`: [`stopped_as_error.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/stopped_as_error.hpp) + +- 🚧 [exec.adapt.general p3.2](https://wg21.link/exec.adapt.general#3.2) verify single child env + +### ✅✅🔴 [exec.associate](https://wg21.link/exec.associate) `execution::associate`: [`associate.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/associate.hpp) + +- 🚧 [exec.adapt.general p3.2](https://wg21.link/exec.adapt.general#3.2) verify single child env + +### ✅✅🔴 [exec.stop.when](https://wg21.link/exec.stop.when) Exposition-only execution::stop_when: [`stop_when.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/stop_when.hpp) + +- 🚧 [exec.adapt.general p3.2](https://wg21.link/exec.adapt.general#3.2) verify single child env + +### ✅✅✅ [exec.spawn.future](https://wg21.link/exec.spawn.future) `execution::spawn_future`: [`spawn_future.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/spawn_future.hpp) + +- 🚧 [exec.adapt.general p3.2](https://wg21.link/exec.adapt.general#3.2) verify single child env + +## ✅✅🔴 [exec.consumers](https://wg21.link/exec.consumers) Sender consumers +### ✅✅🔴 [exec.sync.wait](https://wg21.link/exec.sync.wait) `this_thread::sync_wait`: [`sync_wait.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sync_wait.hpp) +### ✅✅✅ [exec.sync.wait.var](https://wg21.link/exec.sync.wait.var) `this_thread::sync_with_variant`: [`sync_wait_with_variant.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sync_wait_with_variant.hpp) +### ✅✅🔴 [exec.spawn](https://wg21.link/exec.spawn) `execution::spawn`: [`spawn.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/spawn.hpp) +## ✅✅🔴 [exec.cmplsig](https://wg21.link/exec.cmplsig) Completion signatures + +- ✅✅✅ [exec.cmplsig p4](https://wg21.link/exec.cmplsig#4) completion-signature: [`completion_signature.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/completion_signature.hpp) +- ✅✅🔴 [exec.cmplsig p5](https://wg21.link/exec.cmplsig#5) indirect-meta-apply: [`indirect_meta_apply.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/indirect_meta_apply.hpp) +- ✅✅🔴 [exec.cmplsig p5](https://wg21.link/exec.cmplsig#5) always-true: [`gather_signatures.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/gather_signatures.hpp) +- ❎❎🔴 [exec.cmplsig p6](https://wg21.link/exec.cmplsig#6) META-APPLY: [`gather_signatures.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/gather_signatures.hpp) +- ✅✅✅ [exec.cmplsig p6](https://wg21.link/exec.cmplsig#6) gather-signatures: [`gather_signatures.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/gather_signatures.hpp) +- ✅🔴✅ [exec.cmplsig p8](https://wg21.link/exec.cmplsig#8) completion_signatures: [`completion_signatures.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/completion_signatures.hpp) +- ✅✅✅ [exec.cmplsig p8](https://wg21.link/exec.cmplsig#8) value_types_of_t: [`value_types_of_t.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/value_types_of_t.hpp) +- ✅✅✅ [exec.cmplsig p8](https://wg21.link/exec.cmplsig#8) error_types_of_t: [`error_types_of_t.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/error_types_of_t.hpp) +- ✅✅✅ [exec.cmplsig p8](https://wg21.link/exec.cmplsig#8) sends_stopped: [`sends_stopped.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sends_stopped.hpp) + +## ✅✅✅ [exec.envs](https://wg21.link/exec.envs) Queryable utilities +### ✅✅✅ [exec.prop](https://wg21.link/exec.prop) Class template `prop`: [`prop.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/prop.hpp) +### ✅✅✅ [exec.env](https://wg21.link/exec.env) Class template `env`: [`env.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/env.hpp) +## ✅✅✅ [exec.ctx](https://wg21.link/exec.ctx) Execution contexts +### ✅✅✅ [exec.run.loop](https://wg21.link/exec.run.loop) `execution::run_loop` +#### ✅✅✅ [exec.run.loop.general](https://wg21.link/exec.run.loop.general) General: [`run_loop.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/run_loop.hpp) +#### ✅✅❎ [exec.run.loop.types](https://wg21.link/exec.run.loop.types) Associated types +#### ✅✅❎ [exec.run.loop.ctor](https://wg21.link/exec.run.loop.ctor) Constructor and destructor +#### ✅✅❎ [exec.run.loop.members](https://wg21.link/exec.run.loop.members) Member functions +## ✅✅🔴 [exec.coro.util](https://wg21.link/exec.coro.util) Coroutine utilities +### ✅✅🔴 [exec.as.awaitable](https://wg21.link/exec.as.awaitable) `execution::as_awaitable` + +- ✅🔴✅ [exec.as.awaitable p1](https://wg21.link/exec.as.awaitable#1) awaitable-sender: [`awaitable_sender.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/awaitable_sender.hpp) +- 🔴🔴🔴 [exec.as.awaitable p1](https://wg21.link/exec.as.awaitable#1) has-queryable-await-completion-adaptor: 🚨 this name appears to be is unused +- ✅🔴✅ [exec.as.awaitable p2](https://wg21.link/exec.as.awaitable#2) sender-awaitable: : [`sender_awaitable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/sender_awaitable.hpp) +- ✅✅✅ [exec.as.awaitable p7](https://wg21.link/exec.as.awaitable#7) as_awaitable: : [`as_awaitable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/as_awaitable.hpp) +- ✅🔴✅ [exec.as.awaitable p8](https://wg21.link/exec.as.awaitable#8) adapt-for-await-completion: : [`as_awaitable.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/as_awaitable.hpp) + +### ✅✅🔴 [exec.with.awaitable.senders](https://wg21.link/exec.with.awaitable.senders) `execution::with_awaitable_senders`: [`with_awaitable_senders.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/with_awaitable_senders.hpp) +### ✅✅ઑ [exec.affine](https://wg21.link/exec.affine) `execution::affine`: [`affine.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/affine.hpp) +### ✅✅🔴 [exec.inline.scheduler](https://wg21.link/exec.inline.scheduler) `execution::inline_scheduler`: [`inline_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/inline_scheduler.hpp) +### ✅✅🔴 [exec.task.scheduler](https://wg21.link/exec.task.scheduler) `execution::task_scheduler`: [`task_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/task_scheduler.hpp) +### ✅✅🔴 [exec.task](https://wg21.link/exec.task) `execution::task` +#### ✅✅🔴 [task.overview](https://wg21.link/task.overview) `task` overview +#### ✅✅🔴 [task.class](https://wg21.link/task.class) Class template `task` +#### ✅✅🔴 [task.members](https://wg21.link/task.members) `task` members +#### ✅✅🔴 [task.state](https://wg21.link/task.state) Class template `task::state` +#### ✅✅🔴 [task.promise](https://wg21.link/task.promise) Class template `task::promise_type` +## 🔴🔴🔴 [exec.scope](https://wg21.link/exec.scope) Execution scope utilities +### ✅🔴🔴 [exec.scope.concepts](https://wg21.link/exec.scope.concepts) Execution scope concepts + +- ✅🔴🔴 [exec.scope.concepts p1](https://wg21.link/exec.scope.concepts#1) `scope_association`: [`scope_association.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/scope_association.hpp) +- ✅✅🔴 [exec.scope.concepts p3](https://wg21.link/exec.scope.concepts#3) `scope_token`: [`scope_token.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/scope_token.hpp) + +### 🔴🔴🔴 [exec.counting.scopes](https://wg21.link/exec.counting.scopes) Counting scopes +#### 🔴🔴🔴 [exec.counting.scopes.general](https://wg21.link/exec.counting.scopes.general) General + +- ✅✅🔴 [exec.counting.scopes.general p3](https://wg21.link/exec.counting.scopes.general#3) scope-join-t: [`counting_scope_join.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/counting_scope_join.hpp) +- ✅🔴🔴 [exec.counting.scopes.general p3](https://wg21.link/exec.counting.scopes.general#3) scope-state-type: [`counting_scope_join.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/counting_scope_base.hpp) +- 🔴🔴🔴 [exec.counting.scopes.general p5](https://wg21.link/exec.counting.scopes.general#5) association-t + +#### ✅✅🔴 [exec.scope.simple.counting](https://wg21.link/exec.scope.simple.counting) Simple Counting Scope +##### ✅✅🔴 [exec.scope.simple.counting.general](https://wg21.link/exec.scope.simple.counting.general) `simple_counting_scope`: [`simple_counting_scope.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/simple_counting_scope.hpp) +##### ✅✅🔴 [exec.simple.counting.ctor](https://wg21.link/exec.simple.counting.ctor) Constructor and Destructor +##### ✅✅🔴 [exec.simple.counting.mem](https://wg21.link/exec.simple.counting.mem) Members +##### ✅✅🔴 [exec.simple.counting.token](https://wg21.link/exec.simple.counting.token) Token +#### ✅✅🔴 [exec.scope.counting](https://wg21.link/exec.scope.counting) Counting Scope +## ✅✅🔴 [exec.par.scheduler](https://wg21.link/exec.par.scheduler) Parallel scheduler: [`parallel_scheduler.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/parallel_scheduler.hpp) +## ✅✅🔴 [exec.parschedrepl](https://wg21.link/exec.parschedrepl) Namespace `parallel_scheduler_replacement` +### ❎❎❎ [exec.parschedrepl.general](https://wg21.link/exec.parschedrepl.general) General +### ✅✅🔴 [exec.parschedrepl.recvproxy](https://wg21.link/exec.parschedrepl.recvproxy) Receiver proxies: [`parallel_scheduler_replacement.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/parallel_scheduler_replacement.hpp) +### ✅✅🔴 [exec.parschedrepl.query](https://wg21.link/exec.parschedrepl.query) `query_parallel_scheduler_backend`: [`parallel_scheduler_replacement.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/parallel_scheduler_replacement.hpp) +### ✅✅🔴 [exec.parschedrepl.psb](https://wg21.link/exec.parschedrepl.psb) Class `parallel_scheduler_backend`: [`parallel_scheduler_replacement.hpp`](https://github.com/bemanproject/execution/blob/main/include/beman/execution/detail/parallel_scheduler_replacement.hpp) diff --git a/docs/overview.md b/docs/overview.md index b6a98020..068ac448 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -173,7 +173,7 @@ Requirements for _Scheduler_:
sender<Sender> -Senders represent asynchronous work. They may get composed from multiple senders to model a workflow. Senders can’t be run directly. Instead, they are passed to a which connects the sender to a receiver to produce an operation_state which may get started. When using senders to represent work the inner workings shouldn’t matter. They do become relevant when creating sender algorithms. +Senders represent asynchronous work. They may get composed from multiple senders to model a workflow. Senders can’t be run directly. Instead, they are passed to a sender consumer which connects the sender to a receiver to produce an operation_state which may get started. When using senders to represent work the inner workings shouldn’t matter. They do become relevant when creating sender algorithms. Requirements for _Sender_: - The type _Sender_::sender_concept is an alias for `sender_tag` or a type derived thereof or _Sender_ is a suitable _awaitable_. @@ -229,9 +229,9 @@ static_assert(std::execution::sender); The concept sender_in<Sender, Env> tests whether _Sender_ is a sender, _Env_ is a destructible type, and std::execution::get_completion_signatures(_sender_, _env_) yields a specialization of std::execution::completion_signatures.
-sender_to<Sender, Receiver> +sender-to<Sender, Receiver> -The concept sender_to<Sender, Receiver> tests if std::execution::sender_in<_Sender_, std::execution::env_of_t<_Receiver_>> is true, and if _Receiver_ can receive all completion signals which can be sent by _Sender_, and if _Sender_ can be connected to _Receiver_. +The concept sender-to<Sender, Receiver> tests if std::execution::sender_in<_Sender_, std::execution::env_of_t<_Receiver_>> is true, and if _Receiver_ can receive all completion signals which can be sent by _Sender_, and if _Sender_ can be connected to _Receiver_. To determine if _Receiver_ can receive all completion signals from _Sender_ it checks that for each _Signature_ in std::execution::get_completion_signals(_sender_, std::declval<std::execution::env_of_t<_Receiver_>>()) the test std::execution::receiver_of<_Receiver_, _Signature_> yields true. To determine if _Sender_ can be connected to _Receiver_ the concept checks if connect(std::declval<_Sender_>(), std::declval<_Receiver_>) is a valid expression.
@@ -370,7 +370,7 @@ struct alloc_env {
forwarding_query(query) -> bool -**Default**: `false` +Default: `false`
The expression forwarding_query(query) is a `constexpr` query used to determine if the query query should be forwarded when wrapping an environment. The expression is required to be a core constant expression if query is a core constant expression. @@ -378,7 +378,7 @@ The result of the expression is determined as follows:
  1. The result is the value of the expression query.query(forwarding_query) if this expression is valid and `noexcept`.
  2. The result is true if the type of query is publicly derived from forwarding_query.
  3. -
  4. Otherwise the result is false. +
  5. Otherwise the result is false.
@@ -403,11 +403,11 @@ struct custom_t: forwarding_query_t { }; ```
-
+
get_env(queryable) -> env -**Default**: `env<>` +Default: `env<>`
The expression get_env(queryable) is used to get the environment env associated with queryable. To provide a non-default environment for a queryable a `get_env` member needs to be defined. If queryable doesn’t provide the get_env query an object of type env<> is returned. The value of the expression is
    @@ -437,7 +437,7 @@ Note that the `get_env` member is both `const` and `noexcept`.
get_allocator(env) -> allocator -**Default**: none +Default: none
The expression get_allocator(env) returns an allocator for any memory allocations in the respective context. If env doesn’t support this query any attempt to access it will result in a compilation error. The value of the expression get_allocator(env) is the result of as_const(env).query(get_allocator) if
    @@ -464,15 +464,32 @@ struct alloc_env {
+get_completion_domain<Tag>(attrs) -> domain +Default: none +
+The expression get_completion_domain<Tag>(attrs) yields the completion domain for the completion signal Tag associated with the sender attrs. This query can be used to determine the domain a sender sender completes on for a given completion signal Tag by using get_completion_domain<Tag>(get_env(sender), ev...). The value of the expression is +
    +
  1. equivalent to as_const(env).query(get_completion_domain<Tag>, ev...) if + Tag is one of the types set_value_t, set_error_t, or set_stopped_t and the expression is valid;
  2. +
  3. equivalent to as_const(env).query(get_completion_domain<Tag>) if + Tag is one of the types set_value_t, set_error_t, or set_stopped_t and the expression is valid;
  4. +
  5. equivalent to get_completion_domain<set_value_t>(get_env(sender), ev...) if Tag is void and the expression is valid;
  6. +
  7. equivalent to TRY-QUERY(get_completion_scheduler<Tag>(attrs, env...), get_completion_domain<set_value_t>, ev...) if this expression is well-formed;
  8. +
  9. equivalent to default_domain if scheduler<decltype(attrs)> is true and 0u < sizeof...(ev);
  10. +
  11. ill-formed otherwise.
  12. +
+Otherwise the expression is invalid. +
+
get_completion_scheduler<Tag>(env) -> scheduler -**Default**: none +Default: none
-The expression get_complet_scheduler<Tag>(env) yields the completion scheduler for the completion signal Tag associated with env. This query can be used to determine the scheduler a sender sender completes on for a given completion signal Tag by using get_completion_scheduler<Tag>(get_env(sender)). The value of the expression is equivalent to as_const(env).query(get_completion_scheduler<Tag>) if +The expression get_completion_scheduler<Tag>(env) yields the completion scheduler for the completion signal Tag associated with env. This query can be used to determine the scheduler a sender sender completes on for a given completion signal Tag by using get_completion_scheduler<Tag>(get_env(sender)). The value of the expression is equivalent to as_const(env).query(get_completion_scheduler<Tag>) if
    -
  1. Tag is one of the types set_value_t, set_error_t, or set_stopped_t; +
  2. Tag is one of the types set_value_t, set_error_t, or set_stopped_t;
  3. this expression is valid;
  4. this expression is noexcept;
  5. -
  6. the expression’s type satisfies scheduler. +
  7. the expression’s type satisfies scheduler.
Otherwise the expression is invalid.
@@ -511,22 +528,23 @@ The expression get_delegation_scheduler(env) yields the sche
  1. this expression is valid;
  2. this expression is noexcept;
  3. -
  4. the expression’s type satisfies scheduler. +
  5. the expression’s type satisfies scheduler.
Otherwise the expression is invalid.
get_domain(env) -> domain -The expression get_domain(env) yields the domain associated with env. The value of the expression is equivalent to as_const(env).query(get_domain) if +The expression get_domain(env) yields the domain associated with env. The value of the expression is equivalent to
    -
  1. this expression is valid;
  2. -
  3. this expression is noexcept.
  4. +
  5. auto(as_const(env).query(get_domain)) if this expression is valid;
  6. +
  7. otherwise, get_completion_domain<set_value_t>(get_scheduler(env), HIDE-SCHED(env)) if this expression is valid;
  8. +
  9. default_domain() (except env is evaluated).
Otherwise the expression is invalid.
get_forward_progress_guarantee(scheduler) -> forward_progress_guarantee -The expression get_forward_progress_guarantee(scheduler) yields the forward progress guarantee of the scheduler’s execution agent. The value of the expression is equivalent to as_const(env).query(get_scheduler) if +The expression get_forward_progress_guarantee(scheduler) yields the forward progress guarantee of the scheduler’s execution agent. The value of the expression is equivalent to as_const(env).query(get_forward_progress_guarantee) if
  1. this expression is valid;
  2. this expression is noexcept;
  3. @@ -545,6 +563,20 @@ The expression get_scheduler(env) yields the scheduler assoc Otherwise the expression is invalid.
+get_start_scheduler(env) -> scheduler +The expression get_start_scheduler(env) yields the scheduler associated with env. The value of the expression is equivalent to as_const(env).query(get_scheduler) if +
    +
  1. this expression is valid;
  2. +
  3. this expression is noexcept;
  4. +
  5. the expression’s type satisfies scheduler. +
+Otherwise the expression is invalid. + +If the expression get_start_scheduler(get_env(rcvr)) +is well-formed it should yield the scheduler the operation state resulting +from connect(sndr>, rcvr) gets started on. +
+
get_stop_token(env) -> stoppable_token The expression get_stop_token(env) yields the stop token associated with env. The value is the result of the expression as_const(env).query(get_stop_token) if
    @@ -615,13 +647,13 @@ The expression just_stopped() creates a sender which sends a comple read_env(query) -> sender-of<set_value_t(query-result)> The expression read_env(query) creates a sender which sends the result of querying query the environment of the receiver it gets connected to on the `set_value` channel when started. Put differently, it calls set_value(move(receiver), query(get_env(receiver))). For example, in a coroutine it may be useful to extra the stop token associated with the coroutine which can be done using read_env: -```c++\ +```c++ auto token = co_await read_env(get_stop_token); ``` Completions
      -
    • set_value_t(decltype(query(get_env(receiver)))) +
    • set_value_t(decltype(query(get_env(receiver))))
@@ -632,7 +664,7 @@ The expression schedule(scheduler) creates a sender which up
  • set_value_t() upon success
  • set_error_t(Error) upon failure if scheduler may fail
  • -
  • set_stopped_t() upon cancellation if scheduler supports cancellation +
  • set_stopped_t() upon cancellation if scheduler supports cancellation
@@ -646,8 +678,19 @@ a sender which completes on the same scheduler it was started on, even if The primary use of affine is implementing scheduler affinity for task. + +
+associate(sndr, token) -> sender +
+
-`bulk` +bulk(sndr, policy, shape, fun) -> sender +
+
+bulk_chunked(sndr, policy, shape, fun) -> sender +
+
+bulk_unchunked(sndr, policy, shape, fun) -> sender
continues_on(sender, scheduler) -> sender-of<completions-of(sender) + completions-of(schedule(scheduler))> @@ -665,83 +708,423 @@ The expression into_variant(sender) creates a sender which t
let_error(upstream, fun) -> sender +The expression let_error(upstream, fun) yields a sender sndr which uses an error completion (set_error) of upstream as an argument to invoke fun which has to return another sender inner-sndr and the completion of inner-sndr becomes the completion of sndr. If this invocation results in an exception sndr completes with an error completion the result of std::current_exception. If upstream completes successfully (set_value) or with a cancellation (set_stopped) this completion becomes the completion of sndr.
let_stopped(upstream, fun) -> sender +The expression let_stopped(upstream, fun) yields a sender sndr which uses a cancellation completion (set_stopped) of upstream to invoke fun which has to return another sender inner-sndr and the completion of inner-sndr becomes the completion of sndr. If this invocation results in an exception sndr completes with an error completion the result of std::current_exception. If upstream completes successfully (set_value) or with an error (set_error) this completion becomes the completion of sndr.
let_value(upstream, fun) -> sender +The expression let_value(upstream, fun) yields a sender sndr which uses a successful completion (set_value) of upstream as arguments to invoke fun which has to return another sender inner-sndr and the completion of inner-sndr becomes the completion of sndr. If this invocation results in an exception sndr completes with an error completion the result of std::current_exception. If upstream completes with a cancellation (set_stopped) or with an error (set_error) this completion becomes the completion of sndr. +
+
+on(_sched_, _sndr_), on(_sndr, _sched_, _closure_) +The on algorithm is a pipeable sender adaptor. Let on-sender be +
    +
  • _sndr_ when the form on(_sched_, _sndr_) is used;
  • +
  • _closure_(_sndr_) when the form on(_sndr_, _sched_, _closure_) is used.
  • +
+The sender on-sndr is started on _sched_'s execution context. +The on algorithm completes on the original scheduler (obtained using get_start_scheduler) with the result of the on-sndr.
-on(_sched_, _sndr_) +schedule_from(sender) -> sender +The expression schedule_from(sender) yields a +sender which behaves likes sender. The purpose of the schedule_from +is to allow schedulers to customize the way how to transition off the execution context.
-schedule_from(scheduler, sender) -> sender +spawn_future(sndr, token) -> sender
`split`
starts_on(scheduler, sender) -> sender +The expression starts_on(scheduler, sender) yields a sender +which starts sender on the scheduler's context, i.e., +it starts schedule(scheduler) and then starts sender +where the scheduler's sender completes.
-`stopped_as_error` +stopped_as_error(sndr)
-`stopped_as_optional` +stopped_as_optional(sndr)
then(upstream, fun) -> sender +The expression then(upstream, fun) yields a sender sndr which on successful competion of upstream (set_value) calls fun with the arguments passed to set_value and yields the function return as its own result. If the function throws or upstream completes with an error (set_error) the exception or the error becomes sndr's result. If upstream completes with a cancellation (set_stopped). +
+
+unstoppable(sender) -> sender +The expression unstoppable(sender) yields a sender which +passes its receiver's environment to sender except that +the get_stop_token query return never_stop_token: +the resulting sender behaves like sender except that it +is unstoppable.
upon_error(upstream, fun) -> sender +The expression upon_error(upstream, fun) yields a sender sndr which passes an error completion (set_error) of upstream to fun and uses this result of this function invocation for its own successful (set_value) completion. If the function invocation throws std::current_exception() becomes sndr's error (set_error) completion. The success (set_value) and cancellation (set_stopped) completions of upstream are forwarded.
upon_stopped(upstream, fun) -> sender +The expression upon_stopped(upstream, fun) yields a sender sndr which turns a cancellation completion (set_stopped) result of upstream to fun and uses this result of this function invocation for its own successful (set_value) completion. If the function invocation throws std::current_exception() becomes sndr's error (set_error) completion. The success (set_value) and error (set_error) completions of upstream are forwarded.
when_all(sender...) -> sender +The expression when_all(sender...) yields a sender sndr which completes successfully (set_value) when all nested senders sender... completed successfully using the results of the nested senders in order. If any of the senders completes with an error (set_error) or a cancellation (set_stopped) the first such completion becomes the completion of sndr once all nested senders completed. A stop is requested for the stop source(s) whose token was passed to the nested senders.
when_all_with_variant(sender...) -> sender
write_env(sender, env) -> sender +The expression write_env(sender, env) creates a sender +which passes a receiver to sender which combines the environment +env with the environment from the receiver's environment. The +queries from env take precedence over those from the receiver's environment.
### Sender Consumers -- sync_wait(sender) -> std::optional<std::tuple<T...>> +
+sync_wait(sender) -> std::optional<std::tuple<T...>> +
+
+sync_wait_with_variant(sender) -> std::optional<std::variant<std::tuple<T...>...>> +
+
+spawn(sndr, token) -> void +
## Helpers -- `as_awaitable` +
+adapt-for-await-completion(s) +The expression is equivalent to get_await_completion_adaptor(get_env(s))(s) except +that s is evaluated only once. +
+ +
+as_awaitable(expr, promise) +The expression as_awaitable(expr, promise) tries to +create an awaitable from expr and promise. It +tries the following transformations: +
    +
  1. expr.as_awaitable(promise) if this expression is well-formed; otherwise
  2. +
  3. adapt-for-await-completion(transform_sender(expr, get_env(promise))) if this expression is well-formed; otherwise
  4. +
  5. expr if GET-AWAITER(expr) is an awaiter for promise; otherwise.
  6. +
  7. sender-awaitable{adapt-for-await-completion(transform_sender(expr, get_env(promise))), promise} if this expression is well-formed; otherwise
  8. +
  9. expr
  10. +
+ +
- `with_awaitable_sender` - `apply_sender` -- `completion_signatures` +
+completion_signatures<Sig...> +The template specialization completion_signatures<Sig...> is a list +of completion signatures used to declare and compute the result types of senders. + +It has two exposition-only members template: +
    +
  1. count-of(tag) providing a constant expression with the count of tag completions.
  2. +
  3. for-each(fun) invoking fun with a pointer to each of the completion signatures Sig.... The function is used to verify the completion signature types.
  4. +
+
- `completion_signatures_t` - `connect_result_t` - `default_domain` -- `env<T...>` +
+env<Ev...> +The expression env(ev...) creates an environment by combining the environments +ev.... If multiple of the environments support an identical query, the first +one from the first environment is used. +
- `env_of_t` -- `error_types_of_t` +
+error_types_of_t<Sndr, Env = env<>, Variant = variant-or-empty> +The template specialization error_types_of_t<<sndr, Env, Variant> gets Sndr error completion signatures when using the environment Env. The results is represented as a Variant<E... where E... is the list of argument types to the completion signatures. +
- `fwd_env` - `operation_state_tag` +
+prop<Query, Value> +The expression prop(query, value) create an object which can +be queried for query query which results in value. + +
- `receiver_tag` -- `run_loop` +
+run_loop +The class run_loop provides a scheduler to execute work on. It is used +to implement sync_wait(sndr). The public methods on +an object loop of type run_loop are: +
    +
  • loop.get_scheduler() to get a scheduler scheduling work on loop.
  • +
  • loop.finish() to request loop to exit processing work items. Note that run_loop doesn't maintain a stop source, i.e., when this operation is invoked the work doesn't get cancelled.
  • +
  • loop.run() to have the current thread executed work items scheduled on loop. The thread will continue processing work items as long as loop.finish() wasn't called or there is work scheduled on loop. +
+
+ - `scheduler_tag` - `schedule_result_t` - `sender_adaptor_closure` - `sender_tag` + +
+bool sends_stopped<Sndr, Env = env<>> +The Boolean variable sends_stopped<Sndr, Env> is true if the completion signatures of Sndr when using the environment Env contain a cancellation signature (set_stopped_t()). +
+ - `stop_token_of_t` -- `tag_of_t` + +
+tag_of_t<Sndr> +
    +
  • if auto&&[tag, data, children...] = sndr; is well-formed the type decltype(auto(tag));
  • +
  • otherwise ill-formed.
  • +
+
+ - `transform_sender` - `transform_completion_signatures` - `transform_completion_signatures_of` -- `value_types_of_t` +
+value_types_of_t<Sndr, Env = env<>, Tuple = decayed-tuple, Variant = variant-or-empty> +The template specialization value_types_of_t<Sndr, Env, Tuple, Variant> gets Sndr success completion signatures when using the environment Env. The resulting type is a Variant of Tuple elements where each Tuple represents the argument types of one of the value completion signatures. +
## Stop Token - `never_stop_token` - `stop_token` - `inplace_stop_token` + +## Exposition Only + +
+as-except-ptr(err) +Turns err smartly into an exception_ptr: +
    +
  1. if same_as<decay_t<decltype(err)>, exception_ptr>err
  2. +
  3. else if same_as<decay_t<decltype(err)>, error_code>make_exception_ptr(system_error(err))
  4. +
  5. else make_exception_ptr(err)
  6. +
+
+ +
+awaitable-sender<Sndr, Promise> +The concept check awaitable-sender<Sndr, Promise> determines +if the Sndr could work with the environment provided by Promise +and if Promise supports a suitable unhandled_stopped() method. +
+ +
+concept class-type<T> +Determines if the type T is a decayed class type: +decays-to<T, T> && is_class_v<T> +
+ +
+COMMON-DOMAIN(domains...) +The expression COMMON-DOMAIN(domains...) is + +
    +
  • common_type_t<decltype(auto(domains))...>() if this expression is valid
  • +
  • indeterminate_domain<decltype(auto(domains))...>() with duplicates removed from the template arguments
  • +
+
+ +
+COMPL-DOMAIN<Tag>(sndr, ev...) +The expression COMPL-DOMAIN<Tag>(sndr, ev...) gets sndrs completion +domain given the optional environment ev...: + +
    +
  • get_completion_domain(get_env(sndr), ev..) if this expression is well-formed,
  • +
  • indeterminate_domain() otherwise.
  • +
+ +Note: it seems this exposition-only name is actually unused! +
+ +
+concept completion-signature<Signature> +This concept determines if the type Signature is a completion signature, i.e., +if it has one of these three forms: +
    +
  1. set_value_t(T...)
  2. +
  3. set_error_t(T)
  4. +
  5. set_stopped_t()
  6. +
+
+ +
+concept decays-to<From, To> +Determines if To is the result of decaying the type From: +same_as<decay_t<From>, To> +
+ +
+FWD-ENV(env) +The expression FWD-ENV(env) yields a queryable object q supporting only forwardable queries. Let qry be a query object and a... be a possibly emnpty pack of arguments. Then q.query(qry, a...) is +
    +
  • equivalent to env.query(qry, a...) if forwarding_query(qry) is true
  • +
  • ill-formed if forwarding_query(qry) is false
  • +
+
+ +
+FWD-ENV-T(Env) +The type FWD-ENV-T(Env) is decltype(FWD-ENV(decl_val<Env>())). +
+ +
+gather-signatures<Tag, Signatures, Tuple, Variant> +The template specializaton gather-signatures<Tag, Signatures, Tuple, Variant> represents the completion signatures in the type list Signatures using Tag (one of set_value_t, set_error_t, or set_stopped_t) as a Variant of Tuples. Each Tuple has the element types of of one of the matching completion signatures. +
+ +
+concept has-completions<Rcvr, Completions> +This concept determines if an object of type Rcvr supports ech of the completion signatures in Completions. +
+
+ +HIDE-SCHED(q) +For a query object tag and arguments a... the +expressions HIDE-SCHED(q).query(tag, a...) is +
    +
  • undefined if decay_t<decltype(tag)> is get_scheduler_t or get_domain_t
  • +
  • equivalent to q.query(tag, a...) otherwise
  • +
+ +
+infallible-scheduler<Sched> + +Determines if Sched is a scheduler (i.e., scheduler<Sched> is true) +and if Sched's sender has only a set_value_t() completion signature when used with +an environment with an unstoppable_token<Tok> stop token Tok. If the +stop token Tok is not unstoppable_token<Tok> the completion signatures +can include a set_stopped_t() completion signature in addition to the set_value_t() completion signature. +
+ +
+JOIN-ENV(ev1, ev2) +The expression JOIN-ENV(ev1, ev2) yields a queryable object env such that for a query qry and a pack of arguments a... the result of the expression env.query(qry, a...) is + +
    +
  1. equivalent to ev1.query(qry, a...) if this expression is well-formed, otherwise
  2. +
  3. equivalent to ev2.query(qry, a...) if this expression is well-formed, otherwise
  4. +
  5. ill-formed
  6. +
+ +
+ +
+make-sender(tag, data = empty{}, child...) +Creates and object of type basic-sender<decltype(tag), decay_t<decltype(data)>, decay_t<decltype(child)>...> +that's direct initialized with the forwarded arguments. +
+ +
+MAKE-ENV(qry, value) +The expression MAKE-ENV(qry, value) creates a queryable object env such that for a pack of arguments a ... the expression env.query(qry, a...) yields value. +
+ +
+constexpr bool MATCHING-SIG<F1, F2> +Determines if the two function signatures F1 and F2 match: + +If same_as<F1, R1(A1...)> and same_as<F2, R2(A2...)> then +MATCHING-SIG<F1, F2> == same_as<R1(A1&&...), R2(A2&&...)>. +
+ +
+concept movable-value<T> +Determines if objects of type T are movable, non-array values: +move_constructible<decay_t<T>> && constructible_from<decay_t<T>> && (!is_array_v<remove_reference_t<T>>) +
+ +
+struct product-type<T...> +The type product-type<T...> is a tuple-like type. +Instead of constructors it supports only direct initialization, allowing it to hold +inplace constructed elements. It supports p.get<I>() and p.apply(fun) +member functions. +
+ +
+concept queryable<T> +Determines if objects of type T are queryable: +destructible<T>. The semantic implication is +that using the queryable object with query objects behave as required. +
+ +
+query-with-default(tag, env, value) +Returns +
    +
  • tag(env) if this expression is well-formed
  • +
  • value otherwise
  • +
+
+ +
+concept receiver-of<Rcvr, Signatures> +This concept determines if an object of type Rcvr is a receiver (i.e., receiver<Rcvr> is true) and supports each of the completion signatures in Signatures. +
+ +
+SCHED-ENV(sch) +The expression SCHED-ENV(sch) yields a queryable o such that +
    +
  • get_start_scheduler(o) is equivalent to get_start_scheduler(get_env(o))
  • +
  • get_domain(o) is equivalent to get_start_scheduler(get_env(o))
  • +
+
+ +
+sender-awaitable<Sndr, Promise> +The specialization sender-awaitable<Sndr, Promise> is an awaiter implemented by getting the result of the Sndr completion. +
+ +
+concept single-sender<Sndr, Env...> +The test single-sender<Sndr, Env...> is true if Sndr has exactly one successful completion signature when using an environment of type Env.... +
+ +
+single-sender-value-type<Sndr, Env...> +The type single-sender-value-type<Sndr, Env...> is defined if Sndr has exactly one successful completion signature set_value_t(T...) when using an environment of type Env.... The type is +
    +
  • T... if 1u == sizeof...(T) (i.e., there is one element);
  • +
  • void if 0u == sizeof...(T) (i.e., there is no element);
  • +
  • std::tuple<T...> otherwise. +
+
+ +
+stop-when(sndr, token) +
+ +
+TRY-QUERY(q, tag, a...) +Tries to apply the query tag to the queryable object q: +if passing the arguments a... is valid passes these arguments (AS-CONST(q).query(tag, a...)), otherwise +queries q for tag without the arguments (AS-CONST(q).query(tag)), although the +arguments are evaluated. +
+ +
+concept valid-completion-for<Signature, Rcvr> +This concept determines if an object of type Rcvr supports the completion signature Signature. +
+ +
+concept valid-specialization<T, Args...> +This concept determines the class template T can be specialized with arguments Args..., i.e., if T<Args...> is valid. +
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index effe9928..19b8669a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -19,6 +19,15 @@ endif() set(TODO stop_token) #-dk:TODO including that causes a linker error set(TODO suspend_never) #-dk:TODO including that causes ASAN errors +set(TODO + intro_1_hello_world + intro_2_hello_async + playground + sender_demo + stackoverflow + stopping + when_all_cancel +) set(EXAMPLES allocator @@ -26,14 +35,7 @@ set(EXAMPLES doc_just_error doc_just_stopped inspect - intro_1_hello_world - intro_2_hello_async intro_5_consumer - playground - sender_demo - stackoverflow - stopping - when_all_cancel ) if(BEMAN_USE_MODULES) diff --git a/examples/allocator.cpp b/examples/allocator.cpp index b14ed5f0..39ed045c 100644 --- a/examples/allocator.cpp +++ b/examples/allocator.cpp @@ -1,12 +1,17 @@ // examples/allocator.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/examples/doc_just.cpp b/examples/doc_just.cpp index 4979b153..4fdeb9dd 100644 --- a/examples/doc_just.cpp +++ b/examples/doc_just.cpp @@ -1,8 +1,13 @@ // examples/doc_just.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif +#include #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/examples/doc_just_error.cpp b/examples/doc_just_error.cpp index 48a9f98f..72367e0d 100644 --- a/examples/doc_just_error.cpp +++ b/examples/doc_just_error.cpp @@ -1,7 +1,12 @@ // examples/doc_just_error.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/examples/doc_just_stopped.cpp b/examples/doc_just_stopped.cpp index 12971e32..b8d61fea 100644 --- a/examples/doc_just_stopped.cpp +++ b/examples/doc_just_stopped.cpp @@ -1,7 +1,12 @@ // examples/doc_just_stopped.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/examples/inspect.cpp b/examples/inspect.cpp index 92d6ade2..fafbe406 100644 --- a/examples/inspect.cpp +++ b/examples/inspect.cpp @@ -1,6 +1,10 @@ // examples/inspectc.pp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include @@ -8,6 +12,7 @@ #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/examples/intro_1_hello_world.cpp b/examples/intro_1_hello_world.cpp index aacdd25d..a24d1b85 100644 --- a/examples/intro_1_hello_world.cpp +++ b/examples/intro_1_hello_world.cpp @@ -1,11 +1,16 @@ // examples/intro_1_hello_world.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -20,7 +25,7 @@ using namespace std::string_literals; int main() { // clang-format off - auto [result] = + //auto [result] = ex::sync_wait( ex::when_all( ex::just("hello, "s), @@ -30,5 +35,5 @@ int main() { ; // clang-format on - std::cout << result << '\n'; + // std::cout << result << '\n'; } diff --git a/examples/intro_2_hello_async.cpp b/examples/intro_2_hello_async.cpp index e61a4384..d46041b0 100644 --- a/examples/intro_2_hello_async.cpp +++ b/examples/intro_2_hello_async.cpp @@ -1,12 +1,17 @@ // examples/intro_2_hello_async.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/examples/intro_5_consumer.cpp b/examples/intro_5_consumer.cpp index 4cabd6eb..371bae8a 100644 --- a/examples/intro_5_consumer.cpp +++ b/examples/intro_5_consumer.cpp @@ -1,6 +1,10 @@ // examples/intro_5_consumer.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include //-dk:TODO restore if that actually works #include @@ -9,6 +13,7 @@ #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail; diff --git a/examples/modules_and_header.cpp b/examples/modules_and_header.cpp index f7ba4c5b..bcd49cf0 100644 --- a/examples/modules_and_header.cpp +++ b/examples/modules_and_header.cpp @@ -1,7 +1,12 @@ // examples/modules_and_header.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif import beman.execution; namespace ex = beman::execution; diff --git a/examples/playground.cpp b/examples/playground.cpp index 2412f1b6..a3133451 100644 --- a/examples/playground.cpp +++ b/examples/playground.cpp @@ -1,10 +1,15 @@ // examples/playground.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -16,8 +21,9 @@ namespace ex = ::beman::execution; // ---------------------------------------------------------------------------- int main() { - auto [result] = ex::sync_wait(ex::when_all(ex::just(std::string("hello, ")), ex::just(std::string("world"))) | - ex::then([](const auto& s1, const auto& s2) { return s1 + s2; })) - .value_or(std::tuple(std::string("oops"))); - std::cout << "result='" << result << "'\n"; + // auto [result] = + ex::sync_wait(ex::when_all(ex::just(std::string("hello, ")), ex::just(std::string("world"))) | + ex::then([](const auto& s1, const auto& s2) { return s1 + s2; })) + .value_or(std::tuple(std::string("oops"))); + // std::cout << "result='" << result << "'\n"; } diff --git a/examples/sender_demo.cpp b/examples/sender_demo.cpp index a9a4e63f..ee047fac 100644 --- a/examples/sender_demo.cpp +++ b/examples/sender_demo.cpp @@ -1,12 +1,17 @@ // examples/sender_demo.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail; diff --git a/examples/stackoverflow.cpp b/examples/stackoverflow.cpp index 5d25f1ac..275886d1 100644 --- a/examples/stackoverflow.cpp +++ b/examples/stackoverflow.cpp @@ -1,11 +1,16 @@ // examples/stackoverflow.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/examples/stop_token.cpp b/examples/stop_token.cpp index c967e377..e0bae843 100644 --- a/examples/stop_token.cpp +++ b/examples/stop_token.cpp @@ -1,12 +1,17 @@ // examples/stop_token.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/examples/stopping.cpp b/examples/stopping.cpp index 1816df20..4232e069 100644 --- a/examples/stopping.cpp +++ b/examples/stopping.cpp @@ -6,11 +6,16 @@ // which gets started in a thread. To stop this thread // the corresponding stop source is requested to stop. +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -19,6 +24,7 @@ import beman.execution; #endif using namespace std::chrono; +using namespace std::chrono_literals; namespace ex = beman::execution; // ---------------------------------------------------------------------------- diff --git a/examples/when_all_cancel.cpp b/examples/when_all_cancel.cpp index 6c8d58e6..20df52b4 100644 --- a/examples/when_all_cancel.cpp +++ b/examples/when_all_cancel.cpp @@ -1,6 +1,10 @@ // examples/when_all_cancel.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include @@ -10,6 +14,7 @@ #include #include #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/include/beman/execution/detail/as_except_ptr.hpp b/include/beman/execution/detail/as_except_ptr.hpp index 5f9ee471..4e2914d0 100644 --- a/include/beman/execution/detail/as_except_ptr.hpp +++ b/include/beman/execution/detail/as_except_ptr.hpp @@ -25,6 +25,7 @@ namespace beman::execution::detail { * \internal */ template +//-dk:TODO add a proper precondition decltype(auto) as_except_ptr(Error&& error) { if constexpr (::std::same_as<::std::exception_ptr, ::std::decay_t>) { return ::std::forward(error); diff --git a/include/beman/execution/detail/call_with_default.hpp b/include/beman/execution/detail/call_with_default.hpp new file mode 100644 index 00000000..5be42729 --- /dev/null +++ b/include/beman/execution/detail/call_with_default.hpp @@ -0,0 +1,33 @@ +// include/beman/execution/detail/call_with_default.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_CALL_WITH_DEFAULT +#define INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_CALL_WITH_DEFAULT + +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#include +#endif + +// ---------------------------------------------------------------------------- + +namespace beman::execution::detail { +template + requires requires(const Tag& tag, const Env& env, Args&&... args) { tag(env, ::std::forward(args)...); } +constexpr auto call_with_default(Tag, DefaultValue&&, const Env& env, Args&&... args) noexcept( + noexcept(Tag()(env, ::std::forward(args)...))) -> decltype(auto) { + return Tag()(env, ::std::forward(args)...); +} + +template +constexpr auto call_with_default(Tag, DefaultValue&& value, const Env&, const Args&...) noexcept( + noexcept(static_cast(std::forward(value)))) -> decltype(auto) { + return static_cast(std::forward(value)); +} +} // namespace beman::execution::detail + +// ---------------------------------------------------------------------------- + +#endif diff --git a/include/beman/execution/detail/compl_domain.hpp b/include/beman/execution/detail/compl_domain.hpp index e9ed7d2d..c69dca0b 100644 --- a/include/beman/execution/detail/compl_domain.hpp +++ b/include/beman/execution/detail/compl_domain.hpp @@ -11,11 +11,11 @@ import std; #include #endif #ifdef BEMAN_HAS_MODULES -import beman.execution.detail.default_domain; +import beman.execution.detail.indeterminate_domain; import beman.execution.detail.get_completion_domain; import beman.execution.detail.get_env; #else -#include +#include #include #include #endif @@ -30,7 +30,7 @@ constexpr auto compl_domain(const Sndr& sndr, const Envs&... envs) noexcept { }) { return ::beman::execution::get_completion_domain(::beman::execution::get_env(sndr), envs...); } else { - return ::beman::execution::default_domain(); + return ::beman::execution::indeterminate_domain(); } } diff --git a/include/beman/execution/detail/completion_signatures.hpp b/include/beman/execution/detail/completion_signatures.hpp index 39da7195..d27f6380 100644 --- a/include/beman/execution/detail/completion_signatures.hpp +++ b/include/beman/execution/detail/completion_signatures.hpp @@ -29,8 +29,23 @@ namespace beman::execution { * any specializaion are empty. Objects may be created to return them from * functions used for type computations like get_completion_signatures(sender, env). */ -template <::beman::execution::detail::completion_signature...> -struct completion_signatures {}; +template <::beman::execution::detail::completion_signature... Signatures> +struct completion_signatures { + template + struct completion_signatures_tag; + template + struct completion_signatures_tag { + using type = Tag; + }; + template + static constexpr bool count_of(Tag) { + return (::std::same_as::type, Tag> + ... + 0); + } + template + static constexpr void for_each(Fun&& fun) { + (fun(static_cast(nullptr)), ...); + } +}; } // namespace beman::execution // ---------------------------------------------------------------------------- diff --git a/include/beman/execution/detail/data_type.hpp b/include/beman/execution/detail/data_type.hpp new file mode 100644 index 00000000..a4ffc7a8 --- /dev/null +++ b/include/beman/execution/detail/data_type.hpp @@ -0,0 +1,23 @@ +// include/beman/execution/detail/data_type.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_DATA_TYPE +#define INCLUDED_INCLUDE_BEMAN_EXECUTION_DETAIL_DATA_TYPE + +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#include +#endif + +// ---------------------------------------------------------------------------- + +namespace beman::execution::detail { +template +using data_type = decltype(::std::declval().template get<1>()); +} + +// ---------------------------------------------------------------------------- + +#endif diff --git a/include/beman/execution/detail/default_impls.hpp b/include/beman/execution/detail/default_impls.hpp index a22aa866..7b85b999 100644 --- a/include/beman/execution/detail/default_impls.hpp +++ b/include/beman/execution/detail/default_impls.hpp @@ -89,6 +89,9 @@ struct default_impls { } }; static constexpr auto complete = complete_impl{}; + + template + static consteval auto check_types() -> void {} }; } // namespace beman::execution::detail diff --git a/include/beman/execution/detail/fwd_env.hpp b/include/beman/execution/detail/fwd_env.hpp index 8cc7a291..eb332168 100644 --- a/include/beman/execution/detail/fwd_env.hpp +++ b/include/beman/execution/detail/fwd_env.hpp @@ -49,6 +49,9 @@ class fwd_env { }; template fwd_env(Env&&) -> fwd_env; + +template //-dk:TODO detail export +using fwd_env_t = decltype(::beman::execution::detail::fwd_env(::std::declval())); } // namespace beman::execution::detail // ---------------------------------------------------------------------------- diff --git a/include/beman/execution/detail/get_delegation_scheduler.hpp b/include/beman/execution/detail/get_delegation_scheduler.hpp index c9e58e37..7c070e06 100644 --- a/include/beman/execution/detail/get_delegation_scheduler.hpp +++ b/include/beman/execution/detail/get_delegation_scheduler.hpp @@ -24,7 +24,7 @@ namespace beman::execution { struct get_delegation_scheduler_t { template requires requires(Env&& env, const get_delegation_scheduler_t& g) { - { ::std::as_const(env).query(g) } noexcept -> ::beman::execution::scheduler; + { auto(::std::as_const(env).query(g)) } noexcept -> ::beman::execution::scheduler; } auto operator()(Env&& env) const noexcept { return ::std::as_const(env).query(*this); diff --git a/include/beman/execution/detail/get_forward_progress_guarantee.hpp b/include/beman/execution/detail/get_forward_progress_guarantee.hpp index bdc0affa..d11cc89e 100644 --- a/include/beman/execution/detail/get_forward_progress_guarantee.hpp +++ b/include/beman/execution/detail/get_forward_progress_guarantee.hpp @@ -13,8 +13,10 @@ import std; #endif #ifdef BEMAN_HAS_MODULES import beman.execution.detail.forwarding_query; +import beman.execution.detail.almost_scheduler; #else #include +#include #endif // ---------------------------------------------------------------------------- @@ -24,18 +26,13 @@ namespace beman::execution { enum class forward_progress_guarantee { concurrent, parallel, weakly_parallel }; struct get_forward_progress_guarantee_t { - template + template requires requires(const Object& object, const get_forward_progress_guarantee_t& tag) { object.query(tag); } auto operator()(const Object& object) const noexcept -> forward_progress_guarantee { static_assert(::std::same_as); return object.query(*this); } - template - auto operator()(const Object&) const noexcept -> forward_progress_guarantee { - return forward_progress_guarantee::weakly_parallel; - } - static constexpr auto query(const ::beman::execution::forwarding_query_t&) noexcept -> bool { return true; } }; diff --git a/include/beman/execution/detail/get_start_scheduler.hpp b/include/beman/execution/detail/get_start_scheduler.hpp index 3fae8532..43a00bbf 100644 --- a/include/beman/execution/detail/get_start_scheduler.hpp +++ b/include/beman/execution/detail/get_start_scheduler.hpp @@ -12,8 +12,10 @@ import std; #endif #ifdef BEMAN_HAS_MODULES import beman.execution.detail.forwarding_query; +import beman.execution.detail.scheduler; #else #include +#include #endif // ---------------------------------------------------------------------------- @@ -21,7 +23,9 @@ import beman.execution.detail.forwarding_query; namespace beman::execution { struct get_start_scheduler_t : ::beman::execution::forwarding_query_t { template - requires requires(const get_start_scheduler_t& self, const Env& env) { env.query(self); } + requires requires(const get_start_scheduler_t& self, const Env& env) { + { auto(::std::as_const(env).query(self)) } noexcept -> beman::execution::scheduler; + } auto operator()(const Env& env) const noexcept { return env.query(*this); } diff --git a/include/beman/execution/detail/inline_scheduler.hpp b/include/beman/execution/detail/inline_scheduler.hpp index 22ab701e..ec9b85c8 100644 --- a/include/beman/execution/detail/inline_scheduler.hpp +++ b/include/beman/execution/detail/inline_scheduler.hpp @@ -13,23 +13,27 @@ import std; #include #endif #ifdef BEMAN_HAS_MODULES +import beman.execution.detail.completion_signatures; +import beman.execution.detail.get_forward_progress_guarantee; import beman.execution.detail.get_scheduler; -import beman.execution.detail.sender; -import beman.execution.detail.receiver; -import beman.execution.detail.set_value; +import beman.execution.detail.inline_attrs; import beman.execution.detail.operation_state; +import beman.execution.detail.receiver; import beman.execution.detail.scheduler; import beman.execution.detail.scheduler_tag; -import beman.execution.detail.completion_signatures; -import beman.execution.detail.inline_attrs; +import beman.execution.detail.sender; +import beman.execution.detail.set_value; #else -#include -#include -#include -#include -#include #include +#include +#include #include +#include +#include +#include +#include +#include + #endif namespace beman::execution { @@ -38,6 +42,10 @@ struct inline_scheduler { using env = ::beman::execution::detail::inline_attrs<::beman::execution::set_value_t>; + auto query(::beman::execution::get_forward_progress_guarantee_t) const noexcept + -> ::beman::execution::forward_progress_guarantee { + return ::beman::execution::forward_progress_guarantee::weakly_parallel; + } template <::beman::execution::receiver Rcvr> struct state { using operation_state_concept = ::beman::execution::operation_state_tag; diff --git a/include/beman/execution/detail/on.hpp b/include/beman/execution/detail/on.hpp index d737eb75..fec57ba4 100644 --- a/include/beman/execution/detail/on.hpp +++ b/include/beman/execution/detail/on.hpp @@ -12,6 +12,7 @@ import std; #endif #ifdef BEMAN_HAS_MODULES import beman.execution.detail.basic_sender; +import beman.execution.detail.call_with_default; import beman.execution.detail.completion_signatures_of_t; import beman.execution.detail.continues_on; import beman.execution.detail.default_domain; @@ -34,6 +35,8 @@ import beman.execution.detail.set_value; import beman.execution.detail.starts_on; import beman.execution.detail.transform_sender; #else +#include +#include #include #include #include diff --git a/include/beman/execution/detail/operation_state_task.hpp b/include/beman/execution/detail/operation_state_task.hpp index 8209d1a2..148acd38 100644 --- a/include/beman/execution/detail/operation_state_task.hpp +++ b/include/beman/execution/detail/operation_state_task.hpp @@ -70,8 +70,8 @@ struct beman::execution::detail::operation_state_task { using promise_type = ::beman::execution::detail::connect_awaitable_promise; explicit operation_state_task(::std::coroutine_handle<> hndl) noexcept : handle(hndl) {} - operation_state_task(const operation_state_task&) = delete; - operation_state_task(operation_state_task&& other) noexcept : handle(::std::exchange(other.handle, {})) {} + operation_state_task(const operation_state_task&) = delete; + operation_state_task(operation_state_task&& other) = delete; ~operation_state_task() { if (this->handle) this->handle.destroy(); diff --git a/include/beman/execution/detail/product_type.hpp b/include/beman/execution/detail/product_type.hpp index 83dd0592..3ae2fc64 100644 --- a/include/beman/execution/detail/product_type.hpp +++ b/include/beman/execution/detail/product_type.hpp @@ -120,6 +120,7 @@ constexpr auto is_product_type(const ::beman::execution::detail::product_type struct tuple_size<::beman::execution::detail::product_type> @@ -131,6 +132,7 @@ struct tuple_element> { ::std::decay_t>().template get())>; }; } // namespace std +#endif // ---------------------------------------------------------------------------- diff --git a/include/beman/execution/detail/query_with_default.hpp b/include/beman/execution/detail/query_with_default.hpp index f94f315e..14288509 100644 --- a/include/beman/execution/detail/query_with_default.hpp +++ b/include/beman/execution/detail/query_with_default.hpp @@ -27,18 +27,6 @@ query_with_default(Tag, const Env&, Value&& value) noexcept(noexcept(static_cast return static_cast(std::forward(value)); } -template - requires requires(const Tag& tag, const Env& env, Args&&... args) { tag(env, ::std::forward(args)...); } -constexpr auto call_with_default(Tag, DefaultValue&&, const Env& env, Args&&... args) noexcept( - noexcept(Tag()(env, ::std::forward(args)...))) -> decltype(auto) { - return Tag()(env, ::std::forward(args)...); -} - -template -constexpr auto call_with_default(Tag, DefaultValue&& value, const Env&, const Args&...) noexcept( - noexcept(static_cast(std::forward(value)))) -> decltype(auto) { - return static_cast(std::forward(value)); -} } // namespace beman::execution::detail // ---------------------------------------------------------------------------- diff --git a/include/beman/execution/detail/read_env.hpp b/include/beman/execution/detail/read_env.hpp index 67fe95b1..74e658c4 100644 --- a/include/beman/execution/detail/read_env.hpp +++ b/include/beman/execution/detail/read_env.hpp @@ -9,6 +9,7 @@ import std; #else #include +#include #include #include #endif @@ -16,6 +17,7 @@ import std; import beman.execution.detail.basic_sender; import beman.execution.detail.completion_signatures; import beman.execution.detail.completion_signatures_for; +import beman.execution.detail.data_type; import beman.execution.detail.default_impls; import beman.execution.detail.env_of_t; import beman.execution.detail.get_env; @@ -27,6 +29,7 @@ import beman.execution.detail.set_value; #else #include #include +#include #include #include #include @@ -79,7 +82,17 @@ struct read_env_t { } } }; - static constexpr auto start{start_impl{}}; + static constexpr start_impl start{}; + + template + static consteval void check_types() { + using query_type = ::std::decay_t<::beman::execution::detail::data_type>; + if constexpr (!requires(const Env& env) { query_type()(env); }) { + throw ::std::logic_error("query is not invocable with the environment of the receiver"); + } else if constexpr (::std::same_as<::std::invoke_result_t, void>) { + throw ::std::logic_error("query returns void with the environment of the receiver"); + } + } }; }; diff --git a/include/beman/execution/detail/receiver.hpp b/include/beman/execution/detail/receiver.hpp index ec4557a3..3cee0155 100644 --- a/include/beman/execution/detail/receiver.hpp +++ b/include/beman/execution/detail/receiver.hpp @@ -32,7 +32,9 @@ concept receiver = requires(const ::std::remove_cvref_t& rcvr) { { ::beman::execution::get_env(rcvr) } -> ::beman::execution::detail::queryable; } && ::std::move_constructible<::std::remove_cvref_t> && - ::std::constructible_from<::std::remove_cvref_t, Rcvr> && (!::std::is_final_v<::std::remove_cvref_t>); + ::std::constructible_from<::std::remove_cvref_t, Rcvr> && + (!::std::is_final_v<::std::remove_cvref_t>) && + ::std::is_nothrow_move_constructible_v<::std::remove_cvref_t>; } // namespace beman::execution // ---------------------------------------------------------------------------- diff --git a/include/beman/execution/detail/scheduler.hpp b/include/beman/execution/detail/scheduler.hpp index 465304d7..ed859cef 100644 --- a/include/beman/execution/detail/scheduler.hpp +++ b/include/beman/execution/detail/scheduler.hpp @@ -14,10 +14,12 @@ import std; #endif #ifdef BEMAN_HAS_MODULES import beman.execution.detail.almost_scheduler; +import beman.execution.detail.get_forward_progress_guarantee; import beman.execution.detail.schedule; import beman.execution.detail.sender; #else #include +#include #include #include #endif @@ -28,6 +30,9 @@ namespace beman::execution { template concept scheduler = ::beman::execution::detail::almost_scheduler && requires(Scheduler&& sched) { { ::beman::execution::schedule(::std::forward(sched)) } -> ::beman::execution::sender; + { + ::beman::execution::get_forward_progress_guarantee(sched) + } -> ::std::same_as<::beman::execution::forward_progress_guarantee>; } && ::std::equality_comparable<::std::remove_cvref_t> && ::std::copyable<::std::remove_cvref_t>; } // namespace beman::execution diff --git a/include/beman/execution/detail/set_value.hpp b/include/beman/execution/detail/set_value.hpp index d3216a84..c2e4bdc4 100644 --- a/include/beman/execution/detail/set_value.hpp +++ b/include/beman/execution/detail/set_value.hpp @@ -14,6 +14,17 @@ import std; // ---------------------------------------------------------------------------- +#define BEMAN_EXECUTION_SET_VALUE(rcvr, expr) \ + [&]() noexcept(noexcept((expr))) -> void { \ + if constexpr (::std::same_as) { \ + (expr), ::beman::execution::set_value(::std::move((rcvr))); \ + } else { \ + ::beman::execution::set_value(::std::move((rcvr)), (expr)); \ + } \ + }() + +// ---------------------------------------------------------------------------- + namespace beman::execution { /*! * \brief Type of the customization point object for successful completions. diff --git a/include/beman/execution/detail/starts_on.hpp b/include/beman/execution/detail/starts_on.hpp index eb31e8b0..c94dc1a0 100644 --- a/include/beman/execution/detail/starts_on.hpp +++ b/include/beman/execution/detail/starts_on.hpp @@ -139,6 +139,14 @@ struct starts_on_t { return {}; } + template + requires requires(const Tag& tag, const ChildAttrs& child_attrs, Env&&... env) { + tag(::beman::execution::detail::fwd_env(child_attrs), ::std::forward(env)...); + } + auto query(Tag tag, Env&&... env) const noexcept { + return tag(::beman::execution::detail::fwd_env(this->child_attrs), ::std::forward(env)...); + } + Scheduler sch; ChildAttrs child_attrs; }; diff --git a/include/beman/execution/detail/task_scheduler.hpp b/include/beman/execution/detail/task_scheduler.hpp index 859e7524..0de0adcb 100644 --- a/include/beman/execution/detail/task_scheduler.hpp +++ b/include/beman/execution/detail/task_scheduler.hpp @@ -20,6 +20,7 @@ import std; #endif #ifdef BEMAN_HAS_MODULES import beman.execution.detail.bulk; +import beman.execution.detail.call_with_default; import beman.execution.detail.completion_signatures; import beman.execution.detail.connect; import beman.execution.detail.connect_result_t; @@ -59,6 +60,7 @@ import beman.execution.detail.unreachable; import beman.execution.detail.unstoppable_token; #else #include +#include #include #include #include diff --git a/include/beman/execution/execution.hpp b/include/beman/execution/execution.hpp index 0f10f604..a56fd3cb 100644 --- a/include/beman/execution/execution.hpp +++ b/include/beman/execution/execution.hpp @@ -22,7 +22,6 @@ import beman.execution.detail.dependent_sender; import beman.execution.detail.enter_scope_sender_in; import beman.execution.detail.enter_scope_sender; import beman.execution.detail.env; -import beman.execution.detail.execution_policy; import beman.execution.detail.exit_scope_sender_in; import beman.execution.detail.exit_scope_sender_of_t; import beman.execution.detail.exit_scope_sender; diff --git a/src/beman/execution/CMakeLists.txt b/src/beman/execution/CMakeLists.txt index 6e7a3191..751e9909 100644 --- a/src/beman/execution/CMakeLists.txt +++ b/src/beman/execution/CMakeLists.txt @@ -44,6 +44,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/bulk.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/call_result_t.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/callable.hpp + ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/call_with_default.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/check_type_alias_exist.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/child_type.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/class_type.hpp @@ -66,6 +67,7 @@ target_sources( ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/counting_scope.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/counting_scope_base.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/counting_scope_join.hpp + ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/data_type.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/decayed_same_as.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/decayed_tuple.hpp ${PROJECT_SOURCE_DIR}/include/beman/execution/detail/decayed_type_list.hpp @@ -269,6 +271,7 @@ if(BEMAN_USE_MODULES) bulk.cppm call_result_t.cppm callable.cppm + call_with_default.cppm check_type_alias_exist.cppm child_type.cppm class_type.cppm @@ -289,6 +292,7 @@ if(BEMAN_USE_MODULES) counting_scope_base.cppm counting_scope_join.cppm counting_scope.cppm + data_type.cppm decayed_same_as.cppm decayed_tuple.cppm decayed_type_list.cppm diff --git a/src/beman/execution/basic_sender.cppm b/src/beman/execution/basic_sender.cppm index f2caf6d2..57ac9527 100644 --- a/src/beman/execution/basic_sender.cppm +++ b/src/beman/execution/basic_sender.cppm @@ -2,9 +2,14 @@ module; // src/beman/execution/basic_sender.cppm -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include -#include +#endif export module beman.execution.detail.basic_sender; diff --git a/src/beman/execution/call_with_default.cppm b/src/beman/execution/call_with_default.cppm new file mode 100644 index 00000000..8c2bed5e --- /dev/null +++ b/src/beman/execution/call_with_default.cppm @@ -0,0 +1,11 @@ +module; +// src/beman/execution/call_with_default.cppm -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include + +export module beman.execution.detail.call_with_default; + +namespace beman::execution::detail { +export using beman::execution::detail::call_with_default; +} // namespace beman::execution::detail diff --git a/src/beman/execution/data_type.cppm b/src/beman/execution/data_type.cppm new file mode 100644 index 00000000..4c4c9012 --- /dev/null +++ b/src/beman/execution/data_type.cppm @@ -0,0 +1,11 @@ +module; +// src/beman/execution/data_type.cppm -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include + +export module beman.execution.detail.data_type; + +namespace beman::execution::detail { +export using beman::execution::detail::data_type; +} // namespace beman::execution::detail diff --git a/src/beman/execution/execution-detail.cppm b/src/beman/execution/execution-detail.cppm index 916e05da..591f6275 100644 --- a/src/beman/execution/execution-detail.cppm +++ b/src/beman/execution/execution-detail.cppm @@ -21,6 +21,7 @@ export import beman.execution.detail.completion_tag; export import beman.execution.detail.connect_all; export import beman.execution.detail.connect_all_result; export import beman.execution.detail.connect_awaitable; +export import beman.execution.detail.data_type; export import beman.execution.detail.decayed_tuple; export import beman.execution.detail.decayed_typeof; export import beman.execution.detail.decays_to; diff --git a/src/beman/execution/fwd_env.cppm b/src/beman/execution/fwd_env.cppm index e0ad2956..9399f0d1 100644 --- a/src/beman/execution/fwd_env.cppm +++ b/src/beman/execution/fwd_env.cppm @@ -7,5 +7,6 @@ module; export module beman.execution.detail.fwd_env; namespace beman::execution::detail { +export using beman::execution::detail::fwd_env_t; export using beman::execution::detail::fwd_env; } // namespace beman::execution::detail diff --git a/src/beman/execution/product_type.cppm b/src/beman/execution/product_type.cppm index 49326247..5c0f9862 100644 --- a/src/beman/execution/product_type.cppm +++ b/src/beman/execution/product_type.cppm @@ -2,8 +2,13 @@ module; // src/beman/execution/product_type.cppm -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#define BEMAN_EXECUTION_DETAIL_PRODUCT_TYPE_CPPM #include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#include +#endif export module beman.execution.detail.product_type; @@ -14,11 +19,14 @@ export using beman::execution::detail::product_type; } // namespace beman::execution::detail -#if defined(_MSC_VER) && _MSC_VER <= 1944L namespace std { template -struct tuple_size<::beman::execution::detail::product_type>; +struct tuple_size<::beman::execution::detail::product_type> + : ::std::integral_constant::size()> {}; + template <::std::size_t I, typename... T> -struct tuple_element>; +struct tuple_element> { + using type = + ::std::decay_t>().template get())>; +}; } // namespace std -#endif diff --git a/src/beman/execution/query_with_default.cppm b/src/beman/execution/query_with_default.cppm index bb348f29..132bdece 100644 --- a/src/beman/execution/query_with_default.cppm +++ b/src/beman/execution/query_with_default.cppm @@ -8,5 +8,4 @@ export module beman.execution.detail.query_with_default; namespace beman::execution::detail { export using beman::execution::detail::query_with_default; -export using beman::execution::detail::call_with_default; } // namespace beman::execution::detail diff --git a/src/beman/execution/task_scheduler.cppm b/src/beman/execution/task_scheduler.cppm index 7a8b2af8..752eee8c 100644 --- a/src/beman/execution/task_scheduler.cppm +++ b/src/beman/execution/task_scheduler.cppm @@ -2,9 +2,14 @@ module; // src/beman/execution/task_scheduler.cppm -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include -#include +#endif export module beman.execution.detail.task_scheduler; diff --git a/tests/beman/execution/CMakeLists.txt b/tests/beman/execution/CMakeLists.txt index 05e70874..ef8464ad 100644 --- a/tests/beman/execution/CMakeLists.txt +++ b/tests/beman/execution/CMakeLists.txt @@ -5,7 +5,7 @@ if(BEMAN_USE_MODULES) list(APPEND execution_tests execution-module.test stop-token-module.test) endif() -list(APPEND unsupported_execution_tests exec-split.test) +list(APPEND unsupported_execution_tests exec-split.test exec-spawn-future.test) list( APPEND execution_tests @@ -42,6 +42,7 @@ list( exec-opstate.test exec-prop.test exec-queries-expos.test + exec-queryable-concept.test exec-read-env.test exec-recv-concepts.test exec-recv.test @@ -49,6 +50,7 @@ list( exec-run-loop-types.test exec-sched.test exec-schedule.test + exec-schedule-from.test exec-scope-concepts.test exec-scope-counting.test exec-scope-simple-counting.test @@ -61,22 +63,22 @@ list( exec-snd-concepts.test exec-snd-expos.test exec-snd-transform.test - exec-spawn-future.test exec-spawn.test exec-starts-on.test exec-stop-when.test - exec-stopped-as-error.test - exec-stopped-as-optional.test + exec-stopped-err.test + exec-stopped-opt.test exec-sync-wait.test exec-sync-wait-with-variant.test exec-task.test exec-task-scheduler.test exec-then.test - exec-utils-cmplsigs.test + exec-unstoppable.test + exec-cmplsigs.test exec-when-all.test exec-with-awaitable-senders.test exec-within.test - execution-queryable-concept.test + exec-write-env.test execution-syn.test forward-like.test function-objects.test diff --git a/tests/beman/execution/allocator-requirements-general.test.cpp b/tests/beman/execution/allocator-requirements-general.test.cpp index 2cc29807..2d4dd2b0 100644 --- a/tests/beman/execution/allocator-requirements-general.test.cpp +++ b/tests/beman/execution/allocator-requirements-general.test.cpp @@ -1,12 +1,12 @@ // src/beman/execution/tests/allocator-requirements-general.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include #ifdef BEMAN_HAS_MODULES import beman.execution.detail.simple_allocator; #else #include #endif +#include // ---------------------------------------------------------------------------- diff --git a/tests/beman/execution/exec-affine.test.cpp b/tests/beman/execution/exec-affine.test.cpp index 47fe92ab..7a54ab6c 100644 --- a/tests/beman/execution/exec-affine.test.cpp +++ b/tests/beman/execution/exec-affine.test.cpp @@ -1,11 +1,16 @@ // tests/beman/execution/exec-affine.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include +#endif +#include +#include #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -66,6 +71,9 @@ receiver(Sched, awaiter* = nullptr) -> receiver; struct test_scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } struct data { std::size_t connected_{}; @@ -153,6 +161,14 @@ auto test_affine_specializations(Sender&& sender, std::size_t count = 0u) -> voi assert(data.connected_ == count); assert(data.started_ == count); } + +auto test_affine_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::affine(s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::affine(s)); +} } // namespace TEST(affine) { @@ -207,5 +223,7 @@ TEST(affine) { loop.finish(); t.join(); + test_affine_attributes(); + return 0; } diff --git a/tests/beman/execution/exec-associate.test.cpp b/tests/beman/execution/exec-associate.test.cpp index 07144f32..a1ed2e0f 100644 --- a/tests/beman/execution/exec-associate.test.cpp +++ b/tests/beman/execution/exec-associate.test.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include -#include #ifdef BEMAN_HAS_IMPORT_STD import std; #else @@ -14,6 +13,8 @@ import std; #include #include #endif +#include +#include #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -102,6 +103,18 @@ struct scope { static_assert(test_std::scope_token); static_assert(test_std::scope_association); +auto test_associate_attributes() { + test_std::counting_scope scope{}; + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + //-dk:TODO test::test_sender_env(42, test::test_forwardable_attr{}, test_std::associate(s, + // scope.get_token())); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::associate(s, scope.get_token())); + + scope.close(); + test_std::sync_wait(scope.join()); +} } // namespace TEST(exec_associate) { @@ -238,4 +251,5 @@ TEST(exec_associate) { ASSERT(completes_with_value(test_std::just(1) | test_std::associate(null_token{}))); ASSERT(!completes_with_value(test_std::just(1) | test_std::associate(expired_token{}))); } + test_associate_attributes(); } diff --git a/tests/beman/execution/exec-awaitable.test.cpp b/tests/beman/execution/exec-awaitable.test.cpp index 8410614f..f05c9b57 100644 --- a/tests/beman/execution/exec-awaitable.test.cpp +++ b/tests/beman/execution/exec-awaitable.test.cpp @@ -2,9 +2,14 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // #include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-bulk.test.cpp b/tests/beman/execution/exec-bulk.test.cpp index d9978a2e..b67e3201 100644 --- a/tests/beman/execution/exec-bulk.test.cpp +++ b/tests/beman/execution/exec-bulk.test.cpp @@ -1,6 +1,10 @@ // src/beman/execution/tests/exec-bulk.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include @@ -13,7 +17,9 @@ #ifdef __cpp_lib_parallel_algorithm #include #endif +#endif #include +#include #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail.meta.combine; @@ -529,6 +535,24 @@ auto test_bulk_customization() { } #endif +auto test_bulk_attributes() { + // est_std::bulk(test_std::par, vec.size(), [&](std::size_t i) noexcept { result[i] = vec[i] * 2; })); + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::bulk(s, test_std::seq, 1, [](int) {})); + test::test_sender_env( + 84, test::test_non_forwardable_attr{}, test_std::bulk(s, test_std::seq, 1, [](int) {})); + test::test_sender_env( + 42, test::test_forwardable_attr{}, test_std::bulk_chunked(s, test_std::seq, 1, [](int) {})); + test::test_sender_env( + 84, test::test_non_forwardable_attr{}, test_std::bulk_chunked(s, test_std::seq, 1, [](int) {})); + test::test_sender_env( + 42, test::test_forwardable_attr{}, test_std::bulk_unchunked(s, test_std::seq, 1, [](int) {})); + test::test_sender_env( + 84, test::test_non_forwardable_attr{}, test_std::bulk_unchunked(s, test_std::seq, 1, [](int) {})); +} + } // namespace TEST(exec_bulk) { @@ -562,5 +586,6 @@ TEST(exec_bulk) { ASSERT(nullptr == +"the bulk tests shouldn't throw"); } - return EXIT_SUCCESS; + test_bulk_attributes(); + return 0; } diff --git a/tests/beman/execution/exec-utils-cmplsigs.test.cpp b/tests/beman/execution/exec-cmplsigs.test.cpp similarity index 99% rename from tests/beman/execution/exec-utils-cmplsigs.test.cpp rename to tests/beman/execution/exec-cmplsigs.test.cpp index 028e99f0..6672487a 100644 --- a/tests/beman/execution/exec-utils-cmplsigs.test.cpp +++ b/tests/beman/execution/exec-cmplsigs.test.cpp @@ -1,9 +1,14 @@ // src/beman/execution/tests/exec-utils-cmplsigs.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-completion-storage.test.cpp b/tests/beman/execution/exec-completion-storage.test.cpp index f5097267..43c828a7 100644 --- a/tests/beman/execution/exec-completion-storage.test.cpp +++ b/tests/beman/execution/exec-completion-storage.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-within.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #include #ifdef BEMAN_HAS_MODULES diff --git a/tests/beman/execution/exec-connect.test.cpp b/tests/beman/execution/exec-connect.test.cpp index 350b378a..2045f826 100644 --- a/tests/beman/execution/exec-connect.test.cpp +++ b/tests/beman/execution/exec-connect.test.cpp @@ -1,10 +1,15 @@ // src/beman/execution/tests/exec-connect.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-continues-on.test.cpp b/tests/beman/execution/exec-continues-on.test.cpp index b8a64911..6c62ae7d 100644 --- a/tests/beman/execution/exec-continues-on.test.cpp +++ b/tests/beman/execution/exec-continues-on.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-continues-on.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif +#include #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -19,6 +24,9 @@ struct non_sender {}; struct custom_domain : test_std::default_domain {}; struct scheduler { + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } struct env { auto query(const test_std::get_completion_scheduler_t&) const noexcept -> scheduler { return {}; @@ -90,6 +98,15 @@ auto test_use(Scheduler&& scheduler, Sender&& sender) { std::remove_cvref_t>); //-dk:TODO test_std::sync_wait(std::move(s)); } + +auto test_continues_on_attributes() { + test_std::run_loop loop; + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::continues_on(s, loop.get_scheduler())); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::continues_on(s, loop.get_scheduler())); +} } // namespace TEST(exec_continues_on) { @@ -105,4 +122,5 @@ TEST(exec_continues_on) { test_constraints(scheduler{}, sender{}); test_use(scheduler{}, sender{}); + test_continues_on_attributes(); } diff --git a/tests/beman/execution/exec-dependent-sender.test.cpp b/tests/beman/execution/exec-dependent-sender.test.cpp index 8518c5d0..304eec97 100644 --- a/tests/beman/execution/exec-dependent-sender.test.cpp +++ b/tests/beman/execution/exec-dependent-sender.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-dependent-sender.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-domain-default.test.cpp b/tests/beman/execution/exec-domain-default.test.cpp index 22179f47..20d9263d 100644 --- a/tests/beman/execution/exec-domain-default.test.cpp +++ b/tests/beman/execution/exec-domain-default.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-domain-default.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-env.test.cpp b/tests/beman/execution/exec-env.test.cpp index be11d331..f5a2fe65 100644 --- a/tests/beman/execution/exec-env.test.cpp +++ b/tests/beman/execution/exec-env.test.cpp @@ -1,8 +1,13 @@ // tests/beman/execution/exec-env.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-fwd-env.test.cpp b/tests/beman/execution/exec-fwd-env.test.cpp index 58d6f95c..7d2e281d 100644 --- a/tests/beman/execution/exec-fwd-env.test.cpp +++ b/tests/beman/execution/exec-fwd-env.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-fwd-env.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -40,10 +45,15 @@ TEST(exec_fwd_env) { static_assert(not test_std::forwarding_query(0)); static_assert(test_std::forwarding_query(derived())); + static_assert(noexcept(test_std::forwarding_query(derived()))); static_assert(test_std::forwarding_query(static_query<>())); + static_assert(noexcept(test_std::forwarding_query(static_query<>()))); static_assert(not test_std::forwarding_query(static_query())); + static_assert(noexcept(test_std::forwarding_query(static_query()))); static_assert(not test_std::forwarding_query(static_query())); + static_assert(noexcept(test_std::forwarding_query(static_query()))); static_assert(not test_std::forwarding_query(static_query())); + static_assert(noexcept(test_std::forwarding_query(static_query()))); static_assert(test_std::forwarding_query(rvalue_query())); rvalue_query rq{}; diff --git a/tests/beman/execution/exec-general.test.cpp b/tests/beman/execution/exec-general.test.cpp index a763a536..82753d27 100644 --- a/tests/beman/execution/exec-general.test.cpp +++ b/tests/beman/execution/exec-general.test.cpp @@ -1,9 +1,14 @@ // src/beman/execution/tests/exec-general.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -41,6 +46,7 @@ struct non_copyable { }; auto test_movable_value() -> void { + // [exec.general] p6 static_assert(test_detail::movable_value); static_assert(test_detail::movable_value); static_assert(test_detail::movable_value); @@ -54,6 +60,7 @@ auto test_movable_value() -> void { } auto test_matching_sig() -> void { + // [exec.general] p7 static_assert(test_detail::matching_sig); static_assert(not test_detail::matching_sig); @@ -64,6 +71,7 @@ auto test_matching_sig() -> void { } auto test_as_except_ptr() -> void { + // [exec.general] p8 std::exception_ptr ep(std::make_exception_ptr(42)); std::exception_ptr mep(ep); const std::exception_ptr cep(std::make_exception_ptr(42)); diff --git a/tests/beman/execution/exec-get-allocator.test.cpp b/tests/beman/execution/exec-get-allocator.test.cpp index 6a78d23a..4aed310f 100644 --- a/tests/beman/execution/exec-get-allocator.test.cpp +++ b/tests/beman/execution/exec-get-allocator.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-get-allocator.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif +#include #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail; @@ -44,6 +49,9 @@ struct non_const_get_allocator { template auto test_get_allocator(Object&& object) -> void { static_assert(Expect == requires { test_std::get_allocator(::std::forward(object)); }); + if constexpr (Expect) { + static_assert(noexcept(test_std::get_allocator(::std::forward(object)))); + } } } // namespace diff --git a/tests/beman/execution/exec-get-compl-domain.test.cpp b/tests/beman/execution/exec-get-compl-domain.test.cpp index 1f4cb827..212efea1 100644 --- a/tests/beman/execution/exec-get-compl-domain.test.cpp +++ b/tests/beman/execution/exec-get-compl-domain.test.cpp @@ -1,11 +1,18 @@ // tests/beman/execution/exec-get-compl-domain.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif +#include #ifdef BEMAN_HAS_MODULES +import beman.execution.detail.forwarding_query; import beman.execution.detail.get_completion_domain; +import beman.execution.detail.get_forward_progress_guarantee; import beman.execution.detail.set_error; import beman.execution.detail.set_stopped; import beman.execution.detail.set_value; @@ -20,6 +27,8 @@ import beman.execution.detail.get_completion_signatures; import beman.execution.detail.completion_signatures; #else #include +#include +#include #include #include #include @@ -51,7 +60,10 @@ struct test_env {}; template void test_get_completion_domain_template() { - static_assert(Value == requires { beman::execution::get_completion_domain; }); + static_assert( + std::same_as), const test_std::get_completion_domain_t>); + static_assert(test_std::forwarding_query(test_std::get_completion_domain)); + static_assert(Value == requires { test_std::get_completion_domain; }); } template @@ -79,6 +91,9 @@ auto test_get_completion_domain_tag() { template struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } struct state { using operation_state_concept = test_std::operation_state_tag; auto start() noexcept {} diff --git a/tests/beman/execution/exec-get-compl-sched.test.cpp b/tests/beman/execution/exec-get-compl-sched.test.cpp index a4ee47db..cdca0c47 100644 --- a/tests/beman/execution/exec-get-compl-sched.test.cpp +++ b/tests/beman/execution/exec-get-compl-sched.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-get-compl-sched.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -33,6 +38,9 @@ struct sender { template struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } int value{}; auto operator==(const scheduler&) const -> bool = default; auto schedule() noexcept -> sender { return {}; } @@ -100,12 +108,19 @@ TEST(exec_get_compl_sched) { test_tag(e); test_tag(e); + test_std::env<> ev{}; static_assert(::std::same_as(e)), scheduler>); + static_assert(::std::same_as(e, ev)), + scheduler>); static_assert(::std::same_as(e)), scheduler>); + static_assert(::std::same_as(e, ev)), + scheduler>); static_assert(::std::same_as(e)), scheduler>); + static_assert(::std::same_as(e, ev)), + scheduler>); ASSERT(test_std::get_completion_scheduler(e) == scheduler{19}); ASSERT(test_std::get_completion_scheduler(e) == scheduler{20}); ASSERT(test_std::get_completion_scheduler(e) == scheduler{18}); diff --git a/tests/beman/execution/exec-get-delegation-scheduler.test.cpp b/tests/beman/execution/exec-get-delegation-scheduler.test.cpp index f0aab599..6b9435ad 100644 --- a/tests/beman/execution/exec-get-delegation-scheduler.test.cpp +++ b/tests/beman/execution/exec-get-delegation-scheduler.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-get-delegation-scheduler.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -30,6 +35,9 @@ struct env { struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } struct sender { using sender_concept = test_std::sender_tag; @@ -52,9 +60,11 @@ auto env::query(const test_std::get_completion_scheduler_t< template auto test_get_delegation_scheduler(auto&& env) -> void { static_assert(Expect == requires { test_std::get_delegation_scheduler(env); }); - if constexpr (Expect) { + if constexpr (requires { test_std::get_delegation_scheduler(env); }) { ASSERT(17 == test_std::get_delegation_scheduler(env).value); - // ASSERT(Scheduler{env.value} == test_std::get_delegation_scheduler(env)); + static_assert(noexcept(test_std::get_delegation_scheduler(env))); + auto sched{test_std::get_delegation_scheduler(env)}; + ASSERT(decltype(sched){env.value} == test_std::get_delegation_scheduler(env)); } } } // namespace diff --git a/tests/beman/execution/exec-get-domain.test.cpp b/tests/beman/execution/exec-get-domain.test.cpp index 098f8e7f..402a506c 100644 --- a/tests/beman/execution/exec-get-domain.test.cpp +++ b/tests/beman/execution/exec-get-domain.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-get-domain.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -38,6 +43,7 @@ template auto test_get_domain(Object&& object) { if constexpr (requires { test_std::get_domain(object); }) { static_assert(std::same_as); + static_assert(noexcept(test_std::get_domain(object))); } } @@ -48,6 +54,9 @@ struct test_sched_env; struct test_scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() const -> test_sched_sender; auto operator==(const test_scheduler&) const -> bool = default; auto query(test_std::get_completion_domain_t) const noexcept { return sched_domain{}; } @@ -94,6 +103,8 @@ TEST(exec_get_domain) { test_get_domain(non_const_get_domain{}); // falling back to `default_domain` test_get_domain(has_get_domain{42}); test_get_domain(has_get_domain{42}); + test_get_domain(has_get_domain{42}); + test_get_domain(has_get_domain{42}); test_get_domain(overloaded_get_domain{}); static_assert(42 == test_std::get_domain(has_get_domain{42}).value); diff --git a/tests/beman/execution/exec-get-env.test.cpp b/tests/beman/execution/exec-get-env.test.cpp index b24e4fee..a211f9f0 100644 --- a/tests/beman/execution/exec-get-env.test.cpp +++ b/tests/beman/execution/exec-get-env.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-get-env.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -54,12 +59,17 @@ TEST(exec_get_env) { auto e0 = test_std::get_env(0); test::use(e0); static_assert(std::same_as, decltype(e0)>); + static_assert(noexcept(test_std::get_env(0))); + auto e1 = test_std::get_env(non_const{}); test::use(e1); static_assert(std::same_as, decltype(e1)>); + static_assert(noexcept(test_std::get_env(non_const{}))); + auto e2 = test_std::get_env(normal{}); test::use(e2); static_assert(std::same_as); + static_assert(noexcept(test_std::get_env(normal{}))); //-dk:TODO add negative compilation test: auto e3 = test_std::get_env(normal{}); //-dk:TODO add negative compilation test: auto e4 = test_std::get_env(with_non_env{}); } diff --git a/tests/beman/execution/exec-get-scheduler.test.cpp b/tests/beman/execution/exec-get-scheduler.test.cpp index e8f78727..d666041c 100644 --- a/tests/beman/execution/exec-get-scheduler.test.cpp +++ b/tests/beman/execution/exec-get-scheduler.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-get-scheduler.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -15,6 +20,9 @@ import beman.execution; namespace { struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } struct sender { using sender_concept = test_std::sender_tag; }; @@ -35,6 +43,7 @@ TEST(exec_get_scheduler) { static_assert(test_std::forwarding_query(test_std::get_scheduler)); env e{17}; auto sched{test_std::get_scheduler(e)}; + static_assert(noexcept(test_std::get_scheduler(e))); static_assert(::std::same_as); ASSERT(sched == scheduler{17}); } diff --git a/tests/beman/execution/exec-get-start-scheduler.test.cpp b/tests/beman/execution/exec-get-start-scheduler.test.cpp index db27bc84..beb653bd 100644 --- a/tests/beman/execution/exec-get-start-scheduler.test.cpp +++ b/tests/beman/execution/exec-get-start-scheduler.test.cpp @@ -1,8 +1,12 @@ // src/beman/execution/tests/exec-get-start-scheduler.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include -#include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -32,6 +36,9 @@ struct test_sched_env; struct test_scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() const -> test_sched_sender; auto operator==(const test_scheduler&) const -> bool = default; int scheduler_id = 0; @@ -48,7 +55,8 @@ struct test_sched_env { auto query(test_std::get_completion_scheduler_t) const noexcept { return test_scheduler{scheduler_id}; } - int scheduler_id = 0; + auto query(test_std::get_start_scheduler_t) const noexcept { return test_scheduler{scheduler_id + 1}; } + int scheduler_id = 0; }; struct test_sched_sender { @@ -71,6 +79,13 @@ auto test_scheduler::schedule() const -> test_sched_sender { return {scheduler_i } // namespace TEST(exec_get_start_scheduler) { + static_assert(std::same_as); + static_assert(test_std::forwarding_query(test_std::get_start_scheduler)); + auto sched = test_std::get_start_scheduler(test_sched_env{42}); + static_assert(noexcept(test_std::get_start_scheduler(test_sched_env{42}))); + static_assert(::std::same_as); + ASSERT(sched == test_scheduler{43}); + { test_scheduler sched{42}; auto sndr = test_std::schedule(sched) | diff --git a/tests/beman/execution/exec-get-stop-token.test.cpp b/tests/beman/execution/exec-get-stop-token.test.cpp index cde278bd..75151f19 100644 --- a/tests/beman/execution/exec-get-stop-token.test.cpp +++ b/tests/beman/execution/exec-get-stop-token.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-get-stop-token.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -40,6 +45,7 @@ struct inconsistent_get_stop_token { template auto test_get_stop_token(Object&& object) { static_assert(requires { test_std::get_stop_token(object); }); + static_assert(noexcept(test_std::get_stop_token(object))); static_assert(std::same_as); } } // namespace diff --git a/tests/beman/execution/exec-getcomplsigs.test.cpp b/tests/beman/execution/exec-getcomplsigs.test.cpp index c1b7d4e5..e38e6acd 100644 --- a/tests/beman/execution/exec-getcomplsigs.test.cpp +++ b/tests/beman/execution/exec-getcomplsigs.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-getcomplsigs.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-inline-scheduler.test.cpp b/tests/beman/execution/exec-inline-scheduler.test.cpp index 75cc1e31..d12d3ae2 100644 --- a/tests/beman/execution/exec-inline-scheduler.test.cpp +++ b/tests/beman/execution/exec-inline-scheduler.test.cpp @@ -1,8 +1,13 @@ // tests/beman/execution/exec-inline-scheduler.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -24,6 +29,9 @@ struct test_receiver { struct custom_scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } int id{}; struct state { @@ -58,6 +66,9 @@ struct custom_domain { struct sched_with_domain { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } struct state { using operation_state_concept = test_std::operation_state_tag; diff --git a/tests/beman/execution/exec-into-variant.test.cpp b/tests/beman/execution/exec-into-variant.test.cpp index 89e52f91..a72edc80 100644 --- a/tests/beman/execution/exec-into-variant.test.cpp +++ b/tests/beman/execution/exec-into-variant.test.cpp @@ -1,12 +1,18 @@ // src/beman/execution/tests/exec-into-variant.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include +#endif #include +#include #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -117,6 +123,14 @@ auto test_into_variant_stopped() -> void { test_std::start(op); ASSERT(called); } + +auto test_into_variant_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::into_variant(s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::into_variant(s)); +} } // namespace TEST(exec_into_variant) { @@ -155,4 +169,6 @@ TEST(exec_into_variant) { test_std::set_value_t(arg, arg), test_std::set_error_t(error), test_std::set_stopped_t()>>{}); + + test_into_variant_attributes(); } diff --git a/tests/beman/execution/exec-just.test.cpp b/tests/beman/execution/exec-just.test.cpp index 3ce04652..006d2dcb 100644 --- a/tests/beman/execution/exec-just.test.cpp +++ b/tests/beman/execution/exec-just.test.cpp @@ -1,10 +1,15 @@ // src/beman/execution/tests/exec-just.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include +#endif #include #include #ifdef BEMAN_HAS_MODULES diff --git a/tests/beman/execution/exec-let.test.cpp b/tests/beman/execution/exec-let.test.cpp index a7a1e8ce..50e688ec 100644 --- a/tests/beman/execution/exec-let.test.cpp +++ b/tests/beman/execution/exec-let.test.cpp @@ -1,6 +1,10 @@ // src/beman/execution/tests/exec-let.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include @@ -8,7 +12,9 @@ #include #include #include +#endif #include +#include #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -154,6 +160,24 @@ auto test_completion_signatures() -> void { test_std::sync_wait(test::completion_test(test_std::let_value( test_std::just(), []() noexcept { return test_std::just() | test_std::then([]() noexcept {}); }))); } + +auto test_let_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env( + 42, test::test_forwardable_attr{}, test_std::let_value(s, [] { return test_std::just(); })); + test::test_sender_env( + 84, test::test_non_forwardable_attr{}, test_std::let_value(s, [] { return test_std::just(); })); + test::test_sender_env( + 42, test::test_forwardable_attr{}, test_std::let_error(s, [](auto) { return test_std::just(); })); + test::test_sender_env( + 84, test::test_non_forwardable_attr{}, test_std::let_error(s, [](auto) { return test_std::just(); })); + test::test_sender_env( + 42, test::test_forwardable_attr{}, test_std::let_stopped(s, [] { return test_std::just(); })); + test::test_sender_env( + 84, test::test_non_forwardable_attr{}, test_std::let_stopped(s, [] { return test_std::just(); })); +} } // namespace // ---------------------------------------------------------------------------- @@ -174,5 +198,14 @@ TEST(exec_let) { // NOLINTEND(cert-dcl03-c,hicpp-static-assert,misc-static-assert) } - return EXIT_SUCCESS; + test_std::sync_wait(test_std::just() | + (test_std::let_value([] { return test_std::just(); }) | test_std::then([] {}))); + test_std::sync_wait(test_std::just_error(0) | + (test_std::let_error([](auto) { return test_std::just(); }) | test_std::then([] {}))); + test_std::sync_wait(test_std::just_stopped() | + (test_std::let_stopped([] { return test_std::just(); }) | test_std::then([] {}))); + + test_let_attributes(); + + return 0; } diff --git a/tests/beman/execution/exec-on.test.cpp b/tests/beman/execution/exec-on.test.cpp index 6e60a90b..91b2c571 100644 --- a/tests/beman/execution/exec-on.test.cpp +++ b/tests/beman/execution/exec-on.test.cpp @@ -1,8 +1,14 @@ // tests/beman/execution/exec-on.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include +#include #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -59,6 +65,19 @@ struct on_receiver { auto get_env() const noexcept { return test_detail::make_env(test_std::get_scheduler, pool.get_scheduler()); } }; static_assert(test_std::receiver); + +auto test_on_attributes() { + test_std::run_loop loop{}; + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::on(loop.get_scheduler(), s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::on(loop.get_scheduler(), s)); + test::test_sender_env( + 42, test::test_forwardable_attr{}, test_std::on(s, loop.get_scheduler(), test_std::then([]() {}))); + test::test_sender_env( + 84, test::test_non_forwardable_attr{}, test_std::on(s, loop.get_scheduler(), test_std::then([]() {}))); +} } // namespace TEST(exec_on) { @@ -124,4 +143,6 @@ TEST(exec_on) { assert(on_id == pool_id); assert(cont_id == std::this_thread::get_id()); assert(on_id != std::this_thread::get_id()); + + test_on_attributes(); } diff --git a/tests/beman/execution/exec-opstate-start.test.cpp b/tests/beman/execution/exec-opstate-start.test.cpp index 45511ef0..dd510b7e 100644 --- a/tests/beman/execution/exec-opstate-start.test.cpp +++ b/tests/beman/execution/exec-opstate-start.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-opstate-start.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-parallel-scheduler.test.cpp b/tests/beman/execution/exec-parallel-scheduler.test.cpp index 883c903b..3d8d4d08 100644 --- a/tests/beman/execution/exec-parallel-scheduler.test.cpp +++ b/tests/beman/execution/exec-parallel-scheduler.test.cpp @@ -1,7 +1,10 @@ // src/beman/execution/tests/exec-parallel-scheduler.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include @@ -9,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +22,7 @@ #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-prop.test.cpp b/tests/beman/execution/exec-prop.test.cpp index ef97abb3..c230a8af 100644 --- a/tests/beman/execution/exec-prop.test.cpp +++ b/tests/beman/execution/exec-prop.test.cpp @@ -1,8 +1,13 @@ // tests/beman/execution/exec-prop.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/execution-queryable-concept.test.cpp b/tests/beman/execution/exec-queryable-concept.test.cpp similarity index 100% rename from tests/beman/execution/execution-queryable-concept.test.cpp rename to tests/beman/execution/exec-queryable-concept.test.cpp diff --git a/tests/beman/execution/exec-read-env.test.cpp b/tests/beman/execution/exec-read-env.test.cpp index 526d2aa6..4bb751c5 100644 --- a/tests/beman/execution/exec-read-env.test.cpp +++ b/tests/beman/execution/exec-read-env.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-read-env.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -98,10 +103,37 @@ auto test_read_env_completions() -> void { test_std::sync_wait(test_std::when_all(test_std::read_env(test_std::get_stop_token))); test_std::sync_wait(test_std::when_all(test_std::read_env(test_std::get_scheduler))); } + +struct test_query_t { + auto operator()(auto&& env) const noexcept { return env.query(*this); } +}; +inline constexpr test_query_t test_query{}; + +template +struct test_env { + auto query(test_query_t) const noexcept { + if constexpr (Valid) { + return std::allocator{}; + } + } +}; + +auto test_read_env_check_types() -> void { + test_std::read_env_t::impls_for::check_types>(); + test_std::read_env_t::impls_for::check_types>(); +#if 0 + test_std::read_env_t::impls_for::check_types>(); + test_std::read_env_t::impls_for::check_types>(); +#endif +} } // namespace TEST(exec_read_env) { static_assert(std::same_as); test_read_env(); test_read_env_completions(); + test_read_env_check_types(); } diff --git a/tests/beman/execution/exec-recv-concepts.test.cpp b/tests/beman/execution/exec-recv-concepts.test.cpp index 882c2c2c..2faf73d1 100644 --- a/tests/beman/execution/exec-recv-concepts.test.cpp +++ b/tests/beman/execution/exec-recv-concepts.test.cpp @@ -18,6 +18,17 @@ namespace { struct arg {}; struct error {}; +struct not_a_receiver { + auto get_env() const noexcept -> test_std::env<> { return {}; } + auto set_value(auto&&...) && noexcept -> void {} + auto set_error(auto&&) && noexcept -> void {} + auto set_stopped() && noexcept -> void {} +}; + +struct final_receiver final { + using receiver_concept = test_std::receiver_tag; +}; + template struct value_receiver { using receiver_concept = test_std::receiver_tag; @@ -66,6 +77,8 @@ auto test_valid_completion_for() -> void { } auto test_has_completions() -> void { + static_assert(not test_std::receiver); + static_assert(not test_std::receiver); static_assert(test_std::receiver>); static_assert(test_detail::has_completions, test_std::completion_signatures<>>); static_assert(test_detail::has_completions, diff --git a/tests/beman/execution/exec-run-loop-general.test.cpp b/tests/beman/execution/exec-run-loop-general.test.cpp index b24bae9a..0d804455 100644 --- a/tests/beman/execution/exec-run-loop-general.test.cpp +++ b/tests/beman/execution/exec-run-loop-general.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-run-loop-general.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-run-loop-types.test.cpp b/tests/beman/execution/exec-run-loop-types.test.cpp index 27b43597..6c228c33 100644 --- a/tests/beman/execution/exec-run-loop-types.test.cpp +++ b/tests/beman/execution/exec-run-loop-types.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-run-loop-types.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-sched.test.cpp b/tests/beman/execution/exec-sched.test.cpp index 34daf3af..e12b5cf1 100644 --- a/tests/beman/execution/exec-sched.test.cpp +++ b/tests/beman/execution/exec-sched.test.cpp @@ -7,6 +7,7 @@ import beman.execution; #else #include #include +#include #endif // ---------------------------------------------------------------------------- @@ -35,7 +36,10 @@ struct no_scheduler_concept { }; struct not_queryable { - using scheduler_concept = test_std::scheduler_tag; + using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } not_queryable() = default; not_queryable(const not_queryable&) = default; not_queryable(not_queryable&&) = default; @@ -47,17 +51,26 @@ struct not_queryable { }; struct no_schedule { - using scheduler_concept = test_std::scheduler_tag; + using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto operator==(const no_schedule&) const -> bool = default; }; struct not_equality_comparable { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() -> sender> { return {}; } }; struct not_copy_constructible { - using scheduler_concept = test_std::scheduler_tag; + using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } not_copy_constructible(const not_copy_constructible&) = delete; not_copy_constructible(not_copy_constructible&&) = default; ~not_copy_constructible() = default; @@ -69,12 +82,18 @@ struct not_copy_constructible { struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() -> sender> { return {}; } auto operator==(const scheduler&) const -> bool = default; }; struct indirect_completion_scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() -> sender> { return {}; } auto operator==(const indirect_completion_scheduler&) const -> bool = default; }; diff --git a/tests/beman/execution/exec-schedule-from.test.cpp b/tests/beman/execution/exec-schedule-from.test.cpp new file mode 100644 index 00000000..0420cc1a --- /dev/null +++ b/tests/beman/execution/exec-schedule-from.test.cpp @@ -0,0 +1,40 @@ +// tests/beman/execution/exec-schedule-from.test.cpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#include +#endif +#include +#include +#ifdef BEMAN_HAS_MODULES +import beman.execution; +#else +#include +#include +#endif + +// ---------------------------------------------------------------------------- + +namespace { + +auto test_schedule_from() { + auto [a, b] = *test_std::sync_wait(test_std::schedule_from(test_std::just(42, true))); + ASSERT(a == 42); + ASSERT(b); +} + +auto test_schedule_from_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::schedule_from(s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::write_env(s)); +} +} // namespace + +TEST(exec_schedule_from) { + test_schedule_from(); + test_schedule_from_attributes(); +} diff --git a/tests/beman/execution/exec-schedule.test.cpp b/tests/beman/execution/exec-schedule.test.cpp index 46119c16..70e73511 100644 --- a/tests/beman/execution/exec-schedule.test.cpp +++ b/tests/beman/execution/exec-schedule.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-schedule.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-scope-concepts.test.cpp b/tests/beman/execution/exec-scope-concepts.test.cpp index b3960826..7314c659 100644 --- a/tests/beman/execution/exec-scope-concepts.test.cpp +++ b/tests/beman/execution/exec-scope-concepts.test.cpp @@ -1,8 +1,13 @@ // tests/beman/execution/exec-scope-concepts.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-scope-counting.test.cpp b/tests/beman/execution/exec-scope-counting.test.cpp index 3bf32ddc..2408f65b 100644 --- a/tests/beman/execution/exec-scope-counting.test.cpp +++ b/tests/beman/execution/exec-scope-counting.test.cpp @@ -1,9 +1,14 @@ // tests/beman/execution/exec-scope-counting.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-scope-simple-counting.test.cpp b/tests/beman/execution/exec-scope-simple-counting.test.cpp index 8393f6b3..0e7d2364 100644 --- a/tests/beman/execution/exec-scope-simple-counting.test.cpp +++ b/tests/beman/execution/exec-scope-simple-counting.test.cpp @@ -1,9 +1,14 @@ // tests/beman/execution/exec-scope-simple-counting.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-sender-adaptor-closure.test.cpp b/tests/beman/execution/exec-sender-adaptor-closure.test.cpp index 583ca305..2b8c8f54 100644 --- a/tests/beman/execution/exec-sender-adaptor-closure.test.cpp +++ b/tests/beman/execution/exec-sender-adaptor-closure.test.cpp @@ -1,10 +1,13 @@ // tests/beman/execution/exec-sender-adaptor-closure.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include - +#endif #include - #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail; diff --git a/tests/beman/execution/exec-set-error.test.cpp b/tests/beman/execution/exec-set-error.test.cpp index 62f3033b..e64eaa60 100644 --- a/tests/beman/execution/exec-set-error.test.cpp +++ b/tests/beman/execution/exec-set-error.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-set-error.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-set-stopped.test.cpp b/tests/beman/execution/exec-set-stopped.test.cpp index 49d3c9ce..72fb8fb1 100644 --- a/tests/beman/execution/exec-set-stopped.test.cpp +++ b/tests/beman/execution/exec-set-stopped.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-set-stopped.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-set-value.test.cpp b/tests/beman/execution/exec-set-value.test.cpp index dfad10be..90a655df 100644 --- a/tests/beman/execution/exec-set-value.test.cpp +++ b/tests/beman/execution/exec-set-value.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-set-value.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-snd-apply.test.cpp b/tests/beman/execution/exec-snd-apply.test.cpp index 914f2866..abbc9080 100644 --- a/tests/beman/execution/exec-snd-apply.test.cpp +++ b/tests/beman/execution/exec-snd-apply.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-snd-apply.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-snd-concepts.test.cpp b/tests/beman/execution/exec-snd-concepts.test.cpp index 41d7dce9..c4cb6e62 100644 --- a/tests/beman/execution/exec-snd-concepts.test.cpp +++ b/tests/beman/execution/exec-snd-concepts.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-snd-concepts.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-snd-expos.test.cpp b/tests/beman/execution/exec-snd-expos.test.cpp index fc93c276..dcdde83c 100644 --- a/tests/beman/execution/exec-snd-expos.test.cpp +++ b/tests/beman/execution/exec-snd-expos.test.cpp @@ -1,42 +1,48 @@ // src/beman/execution/tests/exec-snd-expos.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include -#include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail; #else -#include -#include -#include +#include +#include #include +#include +#include #include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include #include -#include +#include +#include #include +#include +#include +#include +#include +#include #include +#include #include -#include -#include -#include +#include #include -#include -#include +#include #include -#include -#include -#include -#include +#include #include -#include #include #endif @@ -188,10 +194,38 @@ struct receiver { // ------------------------------------------------------------------------ +template +struct set_value_test_receiver { + using receiver_concept = test_std::receiver_tag; + T& single_arg; + bool& no_arg; + auto set_value(auto&& value) noexcept -> void { + no_arg = false; + single_arg = value; + } +}; + +auto test_set_value_macro() -> void { +#ifdef BEMAN_EXECUTION_SET_VALUE + int value{42}; + bool no_arg{false}; + ASSERT(value == 42); + ASSERT(not no_arg); + BEMAN_EXECUTION_SET_VALUE(set_value_test_receiver{value, no_arg}, []() noexcept { return 43; }()); + ASSERT(value == 43); + ASSERT(not no_arg); + BEMAN_EXECUTION_SET_VALUE(set_value_test_receiver{value, no_arg}, []() noexcept {}()); + ASSERT(value == 43); + ASSERT(no_arg); +#endif +} + template auto test_fwd_env_helper() -> void { env e{42}; static_assert(Expect == requires() { test_detail::fwd_env(e).query(Query()); }); + static_assert(Expect == false || + std::same_as, decltype(test_detail::fwd_env(std::declval()))>); } auto test_fwd_env() -> void { env e{42}; @@ -293,6 +327,9 @@ struct sender { template struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() noexcept -> sender { return {}; } auto operator==(const scheduler&) const -> bool = default; auto query(const test_std::get_domain_t&) const noexcept -> domain { return {}; } @@ -301,6 +338,9 @@ struct scheduler { template <> struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() noexcept -> sender { return {}; } auto operator==(const scheduler&) const -> bool = default; }; @@ -347,7 +387,46 @@ struct env { return {}; } }; + +struct has_value_domain {}; +template <> +struct env { + auto query(const test_std::get_completion_domain_t&) const noexcept -> domain { return {}; } +}; } // namespace completion_domain +auto test_compl_domain() -> void { + namespace cd = completion_domain; + static_assert( + std::same_as(test_std::just(), test_std::env<>())), + decltype(test_std::indeterminate_domain())>); + + static_assert(requires { + test_std::get_completion_domain(test_std::get_env(cd::sender())); + }); + static_assert(requires { + test_std::get_completion_domain(test_std::get_env(cd::sender()), + cd::env()); + }); + static_assert( + std::same_as(cd::sender())), + decltype(cd::domain())>); + static_assert(std::same_as( + cd::sender(), cd::env())), + decltype(cd::domain())>); + + static_assert(std::same_as(cd::sender())), + decltype(test_std::indeterminate_domain())>); + static_assert(std::same_as(cd::sender(), + test_std::env<>())), + decltype(test_std::indeterminate_domain())>); + static_assert(std::same_as(cd::sender(), + cd::env())), + decltype(test_std::indeterminate_domain())>); + static_assert(std::same_as(cd::sender(), + test_std::env<>())), + decltype(test_std::indeterminate_domain())>); +} + auto test_completion_domain() -> void { namespace cd = completion_domain; static_assert(test_std::sender>); @@ -421,6 +500,9 @@ struct get_domain_late_scheduler { auto get_env() const noexcept -> env { return {}; } }; using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() noexcept -> sender { return {}; } auto operator==(const get_domain_late_scheduler&) const -> bool = default; auto query(const test_std::get_domain_t&) const noexcept -> dom { return {}; } @@ -1191,105 +1273,12 @@ auto test_make_sender() -> void { } } -template -struct property { - struct data { - int value{}; - auto operator==(const data&) const -> bool = default; - }; -}; - -struct write_env_env { - struct base {}; - int value{}; - auto query(const property&) const -> property::data { return {this->value}; } -}; -struct write_env_added { - int value{}; - struct added {}; - auto query(const property&) const noexcept -> property::data { return {this->value}; } -}; - -struct write_env_receiver { - using receiver_concept = test_std::receiver_tag; - - bool* result{nullptr}; - - auto get_env() const noexcept -> write_env_env { return {42}; } - auto set_value(bool value) && noexcept -> void { *this->result = value; } -}; - -struct write_env_sender { - using sender_concept = test_std::sender_tag; - using completion_signatures = test_std::completion_signatures; - template - static consteval auto get_completion_signatures() -> completion_signatures { - return {}; - } - template - struct state { - using operation_state_concept = test_std::operation_state_tag; - std::remove_cvref_t receiver; - - auto start() & noexcept -> void { - using base_property = property; - using added_property = property; - bool result{false}; - - if constexpr (requires { - test_std::get_env(receiver).query(base_property{}); - test_std::get_env(receiver).query(added_property{}); - }) { - result = (base_property::data{42} == test_std::get_env(receiver).query(base_property{})) && - (added_property::data{43} == test_std::get_env(receiver).query(added_property{})); - } - - test_std::set_value(::std::move(receiver), result); - } - }; - - template - auto connect(Receiver&& receiver) noexcept -> state { - return {std::forward(receiver)}; - } -}; - -auto test_write_env() -> void { - static_assert(test_std::sender); - static_assert(test_std::receiver); - static_assert(test_detail::queryable); - auto plain_op(test_std::connect(write_env_sender{}, write_env_receiver{})); - static_assert(std::same_as); - static_assert(std::same_as); - using base_property = property; - ASSERT(base_property::data{42} == test_std::get_env(plain_op.receiver).query(base_property{})); - - auto we_sender{test_std::write_env(write_env_sender{}, write_env_added{43})}; - - static_assert(test_std::sender_in); - static_assert(std::same_as, - decltype(test_std::get_completion_signatures())>); - - using we_type = std::remove_cvref_t; - static_assert(std::same_as, - test_std::completion_signatures>); - static_assert(std::same_as>, - test_std::completion_signatures>); - static_assert(std::same_as>, - test_std::completion_signatures>); - static_assert(test_std::sender_in); - static_assert(std::same_as, - decltype(test_std::get_completion_signatures())>); - - static_assert(test_std::sender); - static_assert(std::same_as>); - - bool has_both_properties{false}; - ASSERT(not has_both_properties); - auto we_op{test_std::connect(we_sender, write_env_receiver{&has_both_properties})}; - test_std::start(we_op); - ASSERT(has_both_properties); - test::use(we_op); +template +struct data_sender : test_detail::product_type {}; +auto test_data_type() -> void { + static_assert(std::same_as>>); + static_assert(std::same_as&>>); + static_assert(std::same_as&>>); } template @@ -1304,11 +1293,13 @@ auto test_child_type() -> void { } // namespace TEST(exec_snd_expos) { + test_set_value_macro(); test_fwd_env(); test_make_env(); test_join_env(); test_sched_env(); test_completion_domain(); + test_compl_domain(); test_query_with_default(); test_get_domain_early(); test_get_domain_late(); @@ -1328,6 +1319,6 @@ TEST(exec_snd_expos) { test_completion_signatures_for(); test_basic_sender(); test_make_sender(); - test_write_env(); + test_data_type(); test_child_type(); } diff --git a/tests/beman/execution/exec-snd-transform.test.cpp b/tests/beman/execution/exec-snd-transform.test.cpp index 24621587..8eacf679 100644 --- a/tests/beman/execution/exec-snd-transform.test.cpp +++ b/tests/beman/execution/exec-snd-transform.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/exec-snd-transform.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-spawn-future.test.cpp b/tests/beman/execution/exec-spawn-future.test.cpp index eb59b15d..1dea2a83 100644 --- a/tests/beman/execution/exec-spawn-future.test.cpp +++ b/tests/beman/execution/exec-spawn-future.test.cpp @@ -1,10 +1,16 @@ // tests/beman/execution/exec-spawn-future.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include +#include #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail; @@ -463,6 +469,14 @@ auto test_spawn_future() { } } +auto test_spawn_future_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + //-dk:TODO test::test_sender_env(42, test::test_forwardable_attr{}, test_std::spawn_future(s, + // token{})); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::spawn_future(s, token{})); +} } // namespace TEST(exec_spawn_future) { @@ -483,4 +497,5 @@ TEST(exec_spawn_future) { test_get_allocator(); test_spawn_future(); + test_spawn_future_attributes(); } diff --git a/tests/beman/execution/exec-spawn.test.cpp b/tests/beman/execution/exec-spawn.test.cpp index d326581f..5ec8ef2b 100644 --- a/tests/beman/execution/exec-spawn.test.cpp +++ b/tests/beman/execution/exec-spawn.test.cpp @@ -1,10 +1,15 @@ // tests/beman/execution/exec-spawn.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-starts-on.test.cpp b/tests/beman/execution/exec-starts-on.test.cpp index 743f0886..a2cd6baa 100644 --- a/tests/beman/execution/exec-starts-on.test.cpp +++ b/tests/beman/execution/exec-starts-on.test.cpp @@ -1,9 +1,14 @@ // src/beman/execution/tests/exec-starts-on.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include #include +#include #include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -42,6 +47,9 @@ struct scheduler { } }; using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() -> sender { return {}; } auto operator==(const scheduler&) const -> bool = default; }; @@ -115,6 +123,15 @@ auto test_starts_on_attrs() { std::same_as(std::declval())), scheduler>); } + +auto test_starts_on_attributes() { + test_std::run_loop loop; + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::starts_on(loop.get_scheduler(), s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::starts_on(loop.get_scheduler(), s)); +} } // namespace TEST(exec_starts_on) { @@ -133,4 +150,5 @@ TEST(exec_starts_on) { test_starts_on_completions(); test_starts_on_attrs(); test_starts_on_start_scheduler(); + test_starts_on_attributes(); } diff --git a/tests/beman/execution/exec-stop-when.test.cpp b/tests/beman/execution/exec-stop-when.test.cpp index e15a91ab..8d71110f 100644 --- a/tests/beman/execution/exec-stop-when.test.cpp +++ b/tests/beman/execution/exec-stop-when.test.cpp @@ -1,16 +1,23 @@ // tests/beman/execution/exec-stop-when.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include +#endif #include +#include #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail; #else #include +#include #include #include #include @@ -83,6 +90,16 @@ struct receiver { auto get_env() const noexcept { return env{this->token}; } }; static_assert(test_std::receiver); + +auto test_stop_when_attributes() { + test_std::inplace_stop_source source; + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + //-dk:TODO test::test_sender_env(42, test::test_forwardable_attr{}, test_detail::stop_when(s, + // source.get_token())); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_detail::stop_when(s, source.get_token())); +} } // namespace TEST(exec_stop_when) { @@ -149,4 +166,5 @@ TEST(exec_stop_when) { } test_std::inplace_stop_source source; test_std::sync_wait(test_detail::stop_when(test_std::just(), source.get_token())); + test_stop_when_attributes(); } diff --git a/tests/beman/execution/exec-stopped-as-error.test.cpp b/tests/beman/execution/exec-stopped-err.test.cpp similarity index 78% rename from tests/beman/execution/exec-stopped-as-error.test.cpp rename to tests/beman/execution/exec-stopped-err.test.cpp index 10e420d3..4de73230 100644 --- a/tests/beman/execution/exec-stopped-as-error.test.cpp +++ b/tests/beman/execution/exec-stopped-err.test.cpp @@ -1,10 +1,16 @@ // src/beman/execution/tests/exec-stopped-as-error.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include +#include #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -48,10 +54,19 @@ auto test_stopped_as_std_error_code() -> void { ASSERT(e.code() == std::errc::operation_canceled); } } + +auto test_stopped_as_error_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + //-dk:TODO test::test_sender_env(42, test::test_forwardable_attr{}, test_std::stopped_as_error(s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::stopped_as_error(s)); +} } // namespace // ---------------------------------------------------------------------------- TEST(exec_stopped_as_error) { test_stopped_as_error_signatures(); test_stopped_as_std_error_code(); + test_stopped_as_error_attributes(); } diff --git a/tests/beman/execution/exec-stopped-as-optional.test.cpp b/tests/beman/execution/exec-stopped-opt.test.cpp similarity index 71% rename from tests/beman/execution/exec-stopped-as-optional.test.cpp rename to tests/beman/execution/exec-stopped-opt.test.cpp index 51c87e17..3c5a1844 100644 --- a/tests/beman/execution/exec-stopped-as-optional.test.cpp +++ b/tests/beman/execution/exec-stopped-opt.test.cpp @@ -1,10 +1,16 @@ // src/beman/execution/tests/exec-stopped-as-error.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include +#include #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -35,7 +41,18 @@ auto test_stopped_as_optional() -> void { ASSERT(!opt.has_value()); } +auto test_stopped_as_optional_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::stopped_as_optional(s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::stopped_as_optional(s)); +} + } // namespace // ---------------------------------------------------------------------------- -TEST(exec_stopped_as_optional) { test_stopped_as_optional(); } +TEST(exec_stopped_as_optional) { + test_stopped_as_optional(); + test_stopped_as_optional_attributes(); +} diff --git a/tests/beman/execution/exec-sync-wait-with-variant.test.cpp b/tests/beman/execution/exec-sync-wait-with-variant.test.cpp index 3d73ca61..0359b73d 100644 --- a/tests/beman/execution/exec-sync-wait-with-variant.test.cpp +++ b/tests/beman/execution/exec-sync-wait-with-variant.test.cpp @@ -1,12 +1,17 @@ // src/beman/execution/tests/exec-sync-wait-with-variant.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-sync-wait.test.cpp b/tests/beman/execution/exec-sync-wait.test.cpp index dee72f63..8f8921c8 100644 --- a/tests/beman/execution/exec-sync-wait.test.cpp +++ b/tests/beman/execution/exec-sync-wait.test.cpp @@ -1,10 +1,15 @@ // src/beman/execution/tests/exec-sync-wait.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-task-scheduler.test.cpp b/tests/beman/execution/exec-task-scheduler.test.cpp index f0b41c86..8b5faa98 100644 --- a/tests/beman/execution/exec-task-scheduler.test.cpp +++ b/tests/beman/execution/exec-task-scheduler.test.cpp @@ -1,6 +1,10 @@ // tests/beman/execution/exec-task-scheduler.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include @@ -8,8 +12,8 @@ #include #include #include +#endif #include - #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -31,6 +35,10 @@ namespace { struct async_scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(::beman::execution::get_forward_progress_guarantee_t) const noexcept + -> ::beman::execution::forward_progress_guarantee { + return ::beman::execution::forward_progress_guarantee::weakly_parallel; + } int id{}; template diff --git a/tests/beman/execution/exec-task.test.cpp b/tests/beman/execution/exec-task.test.cpp index 0c9fc50c..1b3f14c0 100644 --- a/tests/beman/execution/exec-task.test.cpp +++ b/tests/beman/execution/exec-task.test.cpp @@ -1,6 +1,10 @@ // tests/beman/execution/exec-task.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include @@ -12,8 +16,8 @@ #include #include #include +#endif #include - #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/tests/beman/execution/exec-then.test.cpp b/tests/beman/execution/exec-then.test.cpp index 101fde6a..8758f2a5 100644 --- a/tests/beman/execution/exec-then.test.cpp +++ b/tests/beman/execution/exec-then.test.cpp @@ -1,13 +1,19 @@ // src/beman/execution/tests/exec-then.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include +#endif #include #include +#include #ifdef BEMAN_HAS_MODULES import beman.execution; #else @@ -261,6 +267,17 @@ auto test_then_completions() { test_std::sync_wait(test::completion_test(test_std::just() | test_std::then([](auto&&...) noexcept {}))); } +auto test_then_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, s | test_std::then([]() {})); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s | test_std::then([]() {})); + test::test_sender_env(42, test::test_forwardable_attr{}, s | test_std::upon_error([](auto) {})); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s | test_std::upon_error([](auto) {})); + test::test_sender_env(42, test::test_forwardable_attr{}, s | test_std::upon_stopped([]() {})); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s | test_std::upon_stopped([]() {})); +} } // namespace TEST(exec_then) { @@ -280,4 +297,5 @@ TEST(exec_then) { test_then_env(); test_then_completions(); + test_then_attributes(); } diff --git a/tests/beman/execution/exec-unstoppable.test.cpp b/tests/beman/execution/exec-unstoppable.test.cpp new file mode 100644 index 00000000..f4bcc4dc --- /dev/null +++ b/tests/beman/execution/exec-unstoppable.test.cpp @@ -0,0 +1,47 @@ +// tests/beman/execution/exec-unstoppable.test.cpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#include +#endif +#include +#include +#ifdef BEMAN_HAS_MODULES +import beman.execution; +#else +#include +#include +#endif + +// ---------------------------------------------------------------------------- + +namespace { + +auto test_unstoppable() -> void { + auto sender = test_std::read_env(test_std::get_stop_token) | test_std::then([](auto stop_token) noexcept { + return test_std::unstoppable_token; + }); + test_std::inplace_stop_source source; + auto [result1] = *test_std::sync_wait( + test_std::write_env(sender, test_std::env{test_std::prop{test_std::get_stop_token, source.get_token()}})); + ASSERT(result1 == false); + auto [result2] = *test_std::sync_wait(test_std::write_env( + test_std::unstoppable(sender), test_std::env{test_std::prop{test_std::get_stop_token, source.get_token()}})); + ASSERT(result2 == true); +} + +auto test_unstoppable_attributes() -> void { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::unstoppable(s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::unstoppable(s)); +} +} // namespace + +TEST(exec_unstoppable) { + test_unstoppable(); + test_unstoppable_attributes(); +} diff --git a/tests/beman/execution/exec-when-all.test.cpp b/tests/beman/execution/exec-when-all.test.cpp index 0e2127f4..1b8ed91b 100644 --- a/tests/beman/execution/exec-when-all.test.cpp +++ b/tests/beman/execution/exec-when-all.test.cpp @@ -1,12 +1,18 @@ // src/beman/execution/tests/exec-when-all.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include +#endif #include +#include // #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -280,6 +286,18 @@ auto test_when_all_with_variant() -> void { }, v1); } + +auto test_when_all_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + //-dk:TODO test::test_sender_env(42, test::test_forwardable_attr{}, test_std::when_all(s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::when_all(s)); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::when_all(s, s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::when_all(s, s)); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::when_all(s, s, s)); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::when_all(s, s, s)); +} } // namespace // ---------------------------------------------------------------------------- @@ -296,4 +314,6 @@ TEST(exec_when_all) { // NOLINTNEXTLINE(cert-dcl03-c,hicpp-static-assert,misc-static-assert) ASSERT(nullptr == "the when_all tests shouldn't throw"); } + + test_when_all_attributes(); } diff --git a/tests/beman/execution/exec-with-awaitable-senders.test.cpp b/tests/beman/execution/exec-with-awaitable-senders.test.cpp index 69ebf6c8..8f3a7e30 100644 --- a/tests/beman/execution/exec-with-awaitable-senders.test.cpp +++ b/tests/beman/execution/exec-with-awaitable-senders.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/exec-with-awaitable-senders.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/exec-within.test.cpp b/tests/beman/execution/exec-within.test.cpp index 91908d9b..e7c714b9 100644 --- a/tests/beman/execution/exec-within.test.cpp +++ b/tests/beman/execution/exec-within.test.cpp @@ -1,9 +1,14 @@ // src/beman/execution/tests/exec-within.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include +#endif #include #include #ifdef BEMAN_HAS_MODULES diff --git a/tests/beman/execution/exec-write-env.test.cpp b/tests/beman/execution/exec-write-env.test.cpp new file mode 100644 index 00000000..61fa8da2 --- /dev/null +++ b/tests/beman/execution/exec-write-env.test.cpp @@ -0,0 +1,136 @@ +// tests/beman/execution/exec-write-env.test.cpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#include +#include +#include +#endif +#ifdef BEMAN_HAS_MODULES +import beman.execution; +import beman.execution.detail; +#else +#include +#endif + +// ---------------------------------------------------------------------------- + +namespace { +template +struct property { + struct data { + int value{}; + auto operator==(const data&) const -> bool = default; + }; +}; + +struct write_env_env { + struct base {}; + int value{}; + auto query(const property&) const -> property::data { return {this->value}; } +}; +struct write_env_added { + int value{}; + struct added {}; + auto query(const property&) const noexcept -> property::data { return {this->value}; } +}; + +struct write_env_receiver { + using receiver_concept = test_std::receiver_tag; + + bool* result{nullptr}; + + auto get_env() const noexcept -> write_env_env { return {42}; } + auto set_value(bool value) && noexcept -> void { *this->result = value; } +}; + +struct write_env_sender { + using sender_concept = test_std::sender_tag; + using completion_signatures = test_std::completion_signatures; + template + static consteval auto get_completion_signatures() -> completion_signatures { + return {}; + } + template + struct state { + using operation_state_concept = test_std::operation_state_tag; + std::remove_cvref_t receiver; + + auto start() & noexcept -> void { + using base_property = property; + using added_property = property; + bool result{false}; + + if constexpr (requires { + test_std::get_env(receiver).query(base_property{}); + test_std::get_env(receiver).query(added_property{}); + }) { + result = (base_property::data{42} == test_std::get_env(receiver).query(base_property{})) && + (added_property::data{43} == test_std::get_env(receiver).query(added_property{})); + } + + test_std::set_value(::std::move(receiver), result); + } + }; + + template + auto connect(Receiver&& receiver) noexcept -> state { + return {std::forward(receiver)}; + } +}; + +auto test_write_env() -> void { + static_assert(test_std::sender); + static_assert(test_std::receiver); + static_assert(test_detail::queryable); + auto plain_op(test_std::connect(write_env_sender{}, write_env_receiver{})); + static_assert(std::same_as); + static_assert(std::same_as); + using base_property = property; + ASSERT(base_property::data{42} == test_std::get_env(plain_op.receiver).query(base_property{})); + + auto we_sender{test_std::write_env(write_env_sender{}, write_env_added{43})}; + + static_assert(test_std::sender_in); + static_assert(std::same_as, + decltype(test_std::get_completion_signatures())>); + + using we_type = std::remove_cvref_t; + static_assert(std::same_as, + test_std::completion_signatures>); + static_assert(std::same_as>, + test_std::completion_signatures>); + static_assert(std::same_as>, + test_std::completion_signatures>); + static_assert(test_std::sender_in); + static_assert(std::same_as, + decltype(test_std::get_completion_signatures())>); + + static_assert(test_std::sender); + static_assert(std::same_as>); + + bool has_both_properties{false}; + ASSERT(not has_both_properties); + auto we_op{test_std::connect(we_sender, write_env_receiver{&has_both_properties})}; + test_std::start(we_op); + ASSERT(has_both_properties); + test::use(we_op); +} + +auto test_write_env_attributes() { + test::sender_env s{42}; + test::test_sender_env(42, test::test_forwardable_attr{}, s); + test::test_sender_env(84, test::test_non_forwardable_attr{}, s); + test::test_sender_env(42, test::test_forwardable_attr{}, test_std::write_env(s, test_std::env<>{})); + test::test_sender_env(84, test::test_non_forwardable_attr{}, test_std::write_env(s, test_std::env<>{})); +} +} // namespace + +TEST(exec_write_env) { + test_write_env(); + test_write_env_attributes(); +} diff --git a/tests/beman/execution/execution-module.test.cpp b/tests/beman/execution/execution-module.test.cpp index d80242ac..b7fb2784 100644 --- a/tests/beman/execution/execution-module.test.cpp +++ b/tests/beman/execution/execution-module.test.cpp @@ -1,8 +1,8 @@ // tests/beman/execution/execution-module.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include import beman.execution; +#include // ---------------------------------------------------------------------------- diff --git a/tests/beman/execution/execution-syn.test.cpp b/tests/beman/execution/execution-syn.test.cpp index bce5e507..6f5234b9 100644 --- a/tests/beman/execution/execution-syn.test.cpp +++ b/tests/beman/execution/execution-syn.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/execution-syn.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -43,6 +48,34 @@ import beman.execution.detail; namespace { auto use(auto&&) -> void {} +auto test_execution_policies() -> void { + struct non_policy {}; + + static_assert(test_std::is_execution_policy::value == false); + static_assert(test_std::is_execution_policy{} == false); + static_assert(test_std::is_execution_policy_v == false); + + static_assert(test_std::is_execution_policy::value == true); + static_assert(test_std::is_execution_policy{} == true); + static_assert(test_std::is_execution_policy_v == true); + static_assert(std::same_as); + + static_assert(test_std::is_execution_policy::value == true); + static_assert(test_std::is_execution_policy{} == true); + static_assert(test_std::is_execution_policy_v == true); + static_assert(std::same_as); + + static_assert(test_std::is_execution_policy::value == true); + static_assert(test_std::is_execution_policy{} == true); + static_assert(test_std::is_execution_policy_v == true); + static_assert(std::same_as); + + static_assert(test_std::is_execution_policy::value == true); + static_assert(test_std::is_execution_policy{} == true); + static_assert(test_std::is_execution_policy_v == true); + static_assert(std::same_as); +} + auto test_queries() -> void { // std static_assert( @@ -76,6 +109,9 @@ struct scheduler { auto get_env() const noexcept -> env { return {}; } }; using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } auto schedule() const noexcept -> sender { return {}; } auto operator==(const scheduler&) const -> bool = default; @@ -491,4 +527,5 @@ TEST(execution_syn) { test_sender_adaptor(); test_as_awaitable(); test_exec_env(); + test_execution_policies(); } diff --git a/tests/beman/execution/forward-like.test.cpp b/tests/beman/execution/forward-like.test.cpp index f846e5ed..6bb2914c 100644 --- a/tests/beman/execution/forward-like.test.cpp +++ b/tests/beman/execution/forward-like.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/forward-like.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif +#include #ifdef BEMAN_HAS_MODULES import beman.execution; import beman.execution.detail.forward_like; diff --git a/tests/beman/execution/functional-syn.test.cpp b/tests/beman/execution/functional-syn.test.cpp index 2f4042eb..4e180438 100644 --- a/tests/beman/execution/functional-syn.test.cpp +++ b/tests/beman/execution/functional-syn.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/functional-syn.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/include/test/execution.hpp b/tests/beman/execution/include/test/execution.hpp index ff7fcb3f..5cab84b1 100644 --- a/tests/beman/execution/include/test/execution.hpp +++ b/tests/beman/execution/include/test/execution.hpp @@ -4,15 +4,23 @@ #ifndef INCLUDED_TEST_EXECUTION #define INCLUDED_TEST_EXECUTION +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#define _SIGNAL_H +#else #include #include #ifndef _MSC_VER -#include -#include -#include #include #endif #include +#include +#endif +#ifndef _MSC_VER +#include +#include +#endif #undef NDEBUG #include @@ -61,24 +69,25 @@ struct throws { auto operator=(const throws&) noexcept(false) -> throws& = default; }; -inline auto death([[maybe_unused]] auto fun, - [[maybe_unused]] ::std::source_location location = test::source_location::current()) noexcept +inline auto death([[maybe_unused]] auto fun/*, + [[maybe_unused]] ::std::source_location location = test::source_location::current()*/) noexcept -> void { #ifndef _MSC_VER switch (::pid_t rc = ::fork()) { default: { int stat{}; ASSERT(rc == ::wait(&stat)); - if (stat == EXIT_SUCCESS) { - ::std::cerr << "failed death test at " << "file=" << location.file_name() << ":" << location.line() << "\n" - << std::flush; - ASSERT(stat != EXIT_SUCCESS); + if (stat == 0) { + ::std::cerr + << "failed death test" /*" at " << "file=" << location.file_name() << ":" << location.line()*/ << "\n" + << std::flush; + ASSERT(stat != 0); } } break; case 0: { ::close(2); fun(); - ::std::exit(EXIT_SUCCESS); + ::std::exit(0); } break; } #endif diff --git a/tests/beman/execution/include/test/optional_sender.hpp b/tests/beman/execution/include/test/optional_sender.hpp index e7719a03..ca82a37b 100644 --- a/tests/beman/execution/include/test/optional_sender.hpp +++ b/tests/beman/execution/include/test/optional_sender.hpp @@ -4,9 +4,14 @@ #ifndef INCLUDED_TESTS_BEMAN_EXECUTION_INCLUDE_TEST_OPTIONAL_SENDER #define INCLUDED_TESTS_BEMAN_EXECUTION_INCLUDE_TEST_OPTIONAL_SENDER -#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif +#include #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/tests/beman/execution/include/test/sender_env.hpp b/tests/beman/execution/include/test/sender_env.hpp new file mode 100644 index 00000000..de4e7492 --- /dev/null +++ b/tests/beman/execution/include/test/sender_env.hpp @@ -0,0 +1,77 @@ +// tests/beman/execution/include/test/sender_env.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_TESTS_BEMAN_EXECUTION_INCLUDE_TEST_SENDER_ENV +#define INCLUDED_TESTS_BEMAN_EXECUTION_INCLUDE_TEST_SENDER_ENV + +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else +#endif +#include +#ifdef BEMAN_HAS_MODULES +import beman.execution; +#else +#include +#endif +#include + +// ---------------------------------------------------------------------------- + +namespace test { +struct test_forwardable_attr : test_std::forwarding_query_t { + template + requires requires(const test_forwardable_attr& attr, const Env& env) { + { env.query(attr) } noexcept -> std::same_as; + } + auto operator()(const Env& env) const noexcept -> int { + return env.query(*this); + } +}; + +struct test_non_forwardable_attr { + template + requires requires(const test_non_forwardable_attr& attr, const Env& env) { + { env.query(attr) } noexcept -> std::same_as; + } + auto operator()(const Env& env) const noexcept -> int { + return env.query(*this); + } +}; + +struct sender_env { + using sender_concept = test_std::sender_tag; + using completion_signatures = test_std::completion_signatures; + + int value{}; + + struct env { + int value{}; + auto query(const test_forwardable_attr&) const noexcept -> int { return this->value; } + auto query(const test_non_forwardable_attr&) const noexcept -> int { return 2 * this->value; } + }; + auto get_env() const noexcept -> env { return env{this->value}; } + + template + static consteval auto get_completion_signatures() -> completion_signatures { + return {}; + } + template + auto connect(Receiver&&) && noexcept { + return test_std::connect(test_std::just(), std::forward(Receiver{})); + } +}; + +template +void test_sender_env(int expected, auto attr, auto&& sender) { + if constexpr (requires { attr(test_std::get_env(sender)); }) { + ASSERT(attr(test_std::get_env(sender)) == expected); + } else { + static_assert(!Expected); + } +} +} // namespace test + +// ---------------------------------------------------------------------------- + +#endif diff --git a/tests/beman/execution/include/test/thread_pool.hpp b/tests/beman/execution/include/test/thread_pool.hpp index 57a33c84..17567ff5 100644 --- a/tests/beman/execution/include/test/thread_pool.hpp +++ b/tests/beman/execution/include/test/thread_pool.hpp @@ -5,12 +5,16 @@ #ifndef INCLUDED_TESTS_BEMAN_EXECUTION_INCLUDE_TEST_THREAD_POOL #define INCLUDED_TESTS_BEMAN_EXECUTION_INCLUDE_TEST_THREAD_POOL +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; @@ -73,6 +77,9 @@ struct test::thread_pool { struct scheduler { using scheduler_concept = test_std::scheduler_tag; + auto query(test_std::get_forward_progress_guarantee_t) const noexcept { + return test_std::forward_progress_guarantee::weakly_parallel; + } struct env { test::thread_pool* pool; diff --git a/tests/beman/execution/issue-174.test.cpp b/tests/beman/execution/issue-174.test.cpp index df5eb3f5..ed6ff5cf 100644 --- a/tests/beman/execution/issue-174.test.cpp +++ b/tests/beman/execution/issue-174.test.cpp @@ -1,8 +1,13 @@ // tests/beman/execution/issue-174.test.cpp *-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/issue-200.test.cpp b/tests/beman/execution/issue-200.test.cpp index e7ac0108..42959e4e 100644 --- a/tests/beman/execution/issue-200.test.cpp +++ b/tests/beman/execution/issue-200.test.cpp @@ -1,9 +1,18 @@ // tests/beman/execution/issue-200.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include -#include +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif +#include +#ifdef BEMAN_HAS_MODULES +import beman.execution; +#else +#include +#endif // ---------------------------------------------------------------------------- diff --git a/tests/beman/execution/meta-combine.test.cpp b/tests/beman/execution/meta-combine.test.cpp index 5e594106..431c1f8d 100644 --- a/tests/beman/execution/meta-combine.test.cpp +++ b/tests/beman/execution/meta-combine.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/meta-combine.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution.detail; diff --git a/tests/beman/execution/meta-filter.test.cpp b/tests/beman/execution/meta-filter.test.cpp index 5aef5582..8213d3fe 100644 --- a/tests/beman/execution/meta-filter.test.cpp +++ b/tests/beman/execution/meta-filter.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/meta-filter.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution.detail; diff --git a/tests/beman/execution/meta-prepend.test.cpp b/tests/beman/execution/meta-prepend.test.cpp index 4923ccc1..bd076399 100644 --- a/tests/beman/execution/meta-prepend.test.cpp +++ b/tests/beman/execution/meta-prepend.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/meta-prepend.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution.detail; diff --git a/tests/beman/execution/meta-transform.test.cpp b/tests/beman/execution/meta-transform.test.cpp index 3f69e132..0d011b52 100644 --- a/tests/beman/execution/meta-transform.test.cpp +++ b/tests/beman/execution/meta-transform.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/meta-transform.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution.detail; diff --git a/tests/beman/execution/meta-unique.test.cpp b/tests/beman/execution/meta-unique.test.cpp index 7a6c7a98..b9271bd7 100644 --- a/tests/beman/execution/meta-unique.test.cpp +++ b/tests/beman/execution/meta-unique.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/meta-unique.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution.detail; diff --git a/tests/beman/execution/non_assignable.test.cpp b/tests/beman/execution/non_assignable.test.cpp index 115a500a..89c3fcef 100644 --- a/tests/beman/execution/non_assignable.test.cpp +++ b/tests/beman/execution/non_assignable.test.cpp @@ -1,7 +1,12 @@ // tests/beman/execution/non_assignable.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution.detail; diff --git a/tests/beman/execution/notify.test.cpp b/tests/beman/execution/notify.test.cpp index f2139d70..6aaa90ca 100644 --- a/tests/beman/execution/notify.test.cpp +++ b/tests/beman/execution/notify.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/notify.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stop-token-module.test.cpp b/tests/beman/execution/stop-token-module.test.cpp index c4f97236..d025bed8 100644 --- a/tests/beman/execution/stop-token-module.test.cpp +++ b/tests/beman/execution/stop-token-module.test.cpp @@ -1,8 +1,8 @@ // tests/beman/execution/stop-token-module.test.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include import beman.execution; +#include // ---------------------------------------------------------------------------- diff --git a/tests/beman/execution/stopcallback-cons.test.cpp b/tests/beman/execution/stopcallback-cons.test.cpp index 6f0c6c55..41bd610e 100644 --- a/tests/beman/execution/stopcallback-cons.test.cpp +++ b/tests/beman/execution/stopcallback-cons.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/stopcallback-cons.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stopcallback-general.test.cpp b/tests/beman/execution/stopcallback-general.test.cpp index 8bc17f27..3b63fdad 100644 --- a/tests/beman/execution/stopcallback-general.test.cpp +++ b/tests/beman/execution/stopcallback-general.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/stopcallback-general.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stopcallback-inplace-cons.test.cpp b/tests/beman/execution/stopcallback-inplace-cons.test.cpp index 3b167967..4e8094d9 100644 --- a/tests/beman/execution/stopcallback-inplace-cons.test.cpp +++ b/tests/beman/execution/stopcallback-inplace-cons.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/stopcallback-inplace-cons.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stopcallback-inplace-general.test.cpp b/tests/beman/execution/stopcallback-inplace-general.test.cpp index fe9a62bf..68122ea0 100644 --- a/tests/beman/execution/stopcallback-inplace-general.test.cpp +++ b/tests/beman/execution/stopcallback-inplace-general.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/stopcallback-inplace-general.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stopsource-cons.test.cpp b/tests/beman/execution/stopsource-cons.test.cpp index 90d9c6e2..edeb5802 100644 --- a/tests/beman/execution/stopsource-cons.test.cpp +++ b/tests/beman/execution/stopsource-cons.test.cpp @@ -1,11 +1,16 @@ // src/beman/execution/tests/stopsource-cons.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #include #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stopsource-general.test.cpp b/tests/beman/execution/stopsource-general.test.cpp index d54dc143..165a910b 100644 --- a/tests/beman/execution/stopsource-general.test.cpp +++ b/tests/beman/execution/stopsource-general.test.cpp @@ -1,7 +1,6 @@ // src/beman/execution/tests/stopsource-general.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stopsource-inplace-cons.test.cpp b/tests/beman/execution/stopsource-inplace-cons.test.cpp index 75cc4a45..252b35f0 100644 --- a/tests/beman/execution/stopsource-inplace-cons.test.cpp +++ b/tests/beman/execution/stopsource-inplace-cons.test.cpp @@ -1,7 +1,6 @@ // src/beman/execution/tests/stopsource-inplace-cons.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stopsource-mem.test.cpp b/tests/beman/execution/stopsource-mem.test.cpp index 10d9d3aa..ce622c4b 100644 --- a/tests/beman/execution/stopsource-mem.test.cpp +++ b/tests/beman/execution/stopsource-mem.test.cpp @@ -2,7 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #ifdef BEMAN_HAS_MODULES import beman.execution; #else diff --git a/tests/beman/execution/stoptoken-concepts.test.cpp b/tests/beman/execution/stoptoken-concepts.test.cpp index 30e35d04..172c57ea 100644 --- a/tests/beman/execution/stoptoken-concepts.test.cpp +++ b/tests/beman/execution/stoptoken-concepts.test.cpp @@ -1,11 +1,16 @@ // src/beman/execution/tests/stoptoken-concepts.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include #ifdef __cpp_lib_jthread #include #endif +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stoptoken-inplace-general.test.cpp b/tests/beman/execution/stoptoken-inplace-general.test.cpp index db3d7567..55387a02 100644 --- a/tests/beman/execution/stoptoken-inplace-general.test.cpp +++ b/tests/beman/execution/stoptoken-inplace-general.test.cpp @@ -1,8 +1,12 @@ // src/beman/execution/tests/stoptoken-inplace-general.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include -#include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/stoptoken-mem.test.cpp b/tests/beman/execution/stoptoken-mem.test.cpp index 3190945d..df5d393e 100644 --- a/tests/beman/execution/stoptoken-mem.test.cpp +++ b/tests/beman/execution/stoptoken-mem.test.cpp @@ -1,8 +1,13 @@ // src/beman/execution/tests/stoptoken-mem.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution; diff --git a/tests/beman/execution/thread-stoptoken-intro.test.cpp b/tests/beman/execution/thread-stoptoken-intro.test.cpp index 191691e7..025d8770 100644 --- a/tests/beman/execution/thread-stoptoken-intro.test.cpp +++ b/tests/beman/execution/thread-stoptoken-intro.test.cpp @@ -1,7 +1,12 @@ // src/beman/execution/tests/thread-stoptoken-intro.test.cpp // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include +#ifdef BEMAN_HAS_IMPORT_STD +import std; +#else #include +#endif #include #ifdef BEMAN_HAS_MODULES import beman.execution;