diff --git a/include/beman/execution/detail/basic_sender.hpp b/include/beman/execution/detail/basic_sender.hpp index 5f46cf82..46adf852 100644 --- a/include/beman/execution/detail/basic_sender.hpp +++ b/include/beman/execution/detail/basic_sender.hpp @@ -66,8 +66,9 @@ inline constexpr sub_apply_t sub_apply{}; template struct basic_sender : ::beman::execution::detail::product_type { //-dk:TODO friend struct ::beman::execution::detail::connect_t; - using sender_concept = ::beman::execution::sender_t; - using indices_for = ::std::index_sequence_for; + using sender_concept = ::beman::execution::sender_t; + using is_basic_sender_tag = void; //-dk:TODO need a better way to detect this is a basic sender + using indices_for = ::std::index_sequence_for; static constexpr ::std::integral_constant<::std::size_t, sizeof...(Child) + 2> size{}; auto get_env() const noexcept -> decltype(auto) { diff --git a/include/beman/execution/detail/inline_scheduler.hpp b/include/beman/execution/detail/inline_scheduler.hpp index 06f8df17..ac2d364f 100644 --- a/include/beman/execution/detail/inline_scheduler.hpp +++ b/include/beman/execution/detail/inline_scheduler.hpp @@ -60,11 +60,6 @@ struct inline_scheduler { static constexpr auto get_env() noexcept -> env { return {}; } - template - static consteval auto get_completion_signatures() noexcept -> completion_signatures { - return {}; - } - template <::beman::execution::receiver Rcvr> auto connect(Rcvr&& receiver) noexcept(::std::is_nothrow_constructible_v<::std::remove_cvref_t, Rcvr>) -> state { diff --git a/include/beman/execution/detail/sender_decompose.hpp b/include/beman/execution/detail/sender_decompose.hpp index ef5f47ce..16137c81 100644 --- a/include/beman/execution/detail/sender_decompose.hpp +++ b/include/beman/execution/detail/sender_decompose.hpp @@ -51,10 +51,12 @@ auto get_sender_data(Sender&& sender) { using sender_type = ::std::remove_cvref_t; static constexpr ::beman::execution::detail::sender_convert_to_any_t at{}; - if constexpr (requires { - sender.template get<0>(); - sender.size(); - }) + if constexpr (!requires { typename sender_type::is_basic_sender_tag; }) { + return ::beman::execution::detail::sender_meta{}; + } else if constexpr (requires { + sender.template get<0>(); + sender.size(); + }) return [&sender]<::std::size_t... I>(::std::index_sequence) { return ::beman::execution::detail::sender_data{ sender.template get<0>(), sender.template get<1>(), ::std::tie(sender.template get<2 + I>()...)}; diff --git a/include/beman/execution/detail/store_receiver.hpp b/include/beman/execution/detail/store_receiver.hpp index 62e4c181..54d88941 100644 --- a/include/beman/execution/detail/store_receiver.hpp +++ b/include/beman/execution/detail/store_receiver.hpp @@ -79,13 +79,15 @@ struct store_receiver_t { template <::beman::execution::sender Sndr, typename Trans> struct sender { using sender_concept = ::beman::execution::sender_t; - template - static consteval auto get_completion_signatures(Env&&... env) noexcept { - return ::beman::execution:: - get_completion_signatures()(::std::declval())), Env...>(); + using trans_t = ::std::remove_cvref_t; + template + static consteval auto get_completion_signatures() noexcept { + return ::beman::execution::get_completion_signatures< + decltype(::std::declval()(::std::declval(), ::std::declval()...)), + Env...>(); } - ::std::remove_cvref_t sndr; - ::std::remove_cvref_t trans; + ::std::remove_cvref_t sndr; + trans_t trans; template <::beman::execution::receiver Receiver> auto connect(Receiver&& r) && { diff --git a/tests/beman/execution/exec-domain-default.test.cpp b/tests/beman/execution/exec-domain-default.test.cpp index f9ae8657..57042766 100644 --- a/tests/beman/execution/exec-domain-default.test.cpp +++ b/tests/beman/execution/exec-domain-default.test.cpp @@ -62,7 +62,8 @@ struct tag { template struct tagged_sender { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; tag t{}; int value{17}; int args{}; diff --git a/tests/beman/execution/exec-snd-concepts.test.cpp b/tests/beman/execution/exec-snd-concepts.test.cpp index 03ebd99c..5a3a2be7 100644 --- a/tests/beman/execution/exec-snd-concepts.test.cpp +++ b/tests/beman/execution/exec-snd-concepts.test.cpp @@ -33,25 +33,29 @@ struct own_sender { struct tag_t {}; struct tagged_sender { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; tag_t tag; int data; }; struct tagged_sender1 { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; tag_t tag; int data; int child1; }; struct tagged_sender2 { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; tag_t tag; int data; int child1; int child2; }; struct tagged_sender3 { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; tag_t tag; int data; int child1; @@ -59,7 +63,8 @@ struct tagged_sender3 { int child3; }; struct tagged_sender4 { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; tag_t tag; int data; int child1; @@ -68,19 +73,24 @@ struct tagged_sender4 { int child4; }; struct product_sender0 : test_detail::product_type { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; }; struct product_sender1 : test_detail::product_type { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; }; struct product_sender2 : test_detail::product_type { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; }; struct product_sender3 : test_detail::product_type { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; }; struct product_sender4 : test_detail::product_type { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; }; // ------------------------------------------------------------------------- diff --git a/tests/beman/execution/exec-snd-expos.test.cpp b/tests/beman/execution/exec-snd-expos.test.cpp index aca8b075..67de17a6 100644 --- a/tests/beman/execution/exec-snd-expos.test.cpp +++ b/tests/beman/execution/exec-snd-expos.test.cpp @@ -112,8 +112,9 @@ struct operation_state : test_detail::immovable { struct sender0 { struct env {}; - using sender_concept = test_std::sender_t; - using indices_for = ::std::index_sequence_for<>; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; + using indices_for = ::std::index_sequence_for<>; tag t{}; int* data{}; template @@ -124,8 +125,9 @@ struct sender0 { }; struct sender1 { - using sender_concept = test_std::sender_t; - using indices_for = ::std::index_sequence_for; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; + using indices_for = ::std::index_sequence_for; tag t{}; int* data{}; sender0 c0{}; @@ -136,8 +138,9 @@ struct sender1 { }; struct sender2 { - using sender_concept = test_std::sender_t; - using indices_for = ::std::index_sequence_for; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; + using indices_for = ::std::index_sequence_for; tag t{}; int* data{}; sender0 c0{}; @@ -149,8 +152,9 @@ struct sender2 { }; struct sender3 { - using sender_concept = test_std::sender_t; - using indices_for = ::std::index_sequence_for; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; + using indices_for = ::std::index_sequence_for; tag t{}; int* data{}; sender0 c0{}; @@ -163,8 +167,9 @@ struct sender3 { }; struct sender4 { - using sender_concept = test_std::sender_t; - using indices_for = ::std::index_sequence_for; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; + using indices_for = ::std::index_sequence_for; tag t{}; int* data{}; sender0 c0{}; @@ -547,21 +552,25 @@ auto test_default_impls_get_state() -> void { auto operator==(const data&) const -> bool = default; }; struct local_sender0 { + using is_basic_sender_tag = void; local_tag t{}; data d{1, 2}; }; struct local_sender1 { + using is_basic_sender_tag = void; local_tag t{}; data d{1, 2}; int i1{}; }; struct local_sender2 { + using is_basic_sender_tag = void; local_tag t{}; data d{1, 2}; int i1{}; int i2{}; }; struct local_sender3 { + using is_basic_sender_tag = void; local_tag t{}; data d{1, 2}; int i1{}; @@ -569,6 +578,7 @@ auto test_default_impls_get_state() -> void { int i3{}; }; struct local_sender4 { + using is_basic_sender_tag = void; local_tag t{}; data d{1, 2}; int i1{}; @@ -665,6 +675,7 @@ auto test_state_type() -> void { }; struct state {}; struct sender { + using is_basic_sender_tag = void; local_tag t; state s; }; @@ -679,6 +690,7 @@ auto test_basic_state() -> void { }; struct data {}; struct local_sender { + using is_basic_sender_tag = void; local_tag t; data d; }; @@ -717,10 +729,12 @@ auto test_env_type() -> void { struct data {}; struct local_env {}; struct local_sender { + using is_basic_sender_tag = void; local_tag t; data d; }; struct sender_with_env { + using is_basic_sender_tag = void; local_tag t; data d; auto get_env() const noexcept -> local_env { return {}; } @@ -750,8 +764,9 @@ auto test_basic_receiver() -> void { auto operator==(const err&) const -> bool = default; }; struct local_sender { - local_tag t{}; - data d{}; + using is_basic_sender_tag = local_tag; + is_basic_sender_tag t{}; + data d{}; }; struct local_receiver { T value{}; @@ -766,6 +781,7 @@ auto test_basic_receiver() -> void { T value; }; using basic_receiver = test_detail::basic_receiver; + static_assert(requires { typename local_sender::is_basic_sender_tag; }); static_assert(test_std::receiver); static_assert(std::same_as); static_assert( @@ -1098,7 +1114,8 @@ struct basic_sender_tag { struct data {}; struct tagged_sender : test_detail::product_type { - using sender_concept = test_std::sender_t; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; }; } // namespace namespace std { diff --git a/tests/beman/execution/exec-snd-transform.test.cpp b/tests/beman/execution/exec-snd-transform.test.cpp index 6526dd9f..2a1a2497 100644 --- a/tests/beman/execution/exec-snd-transform.test.cpp +++ b/tests/beman/execution/exec-snd-transform.test.cpp @@ -44,8 +44,9 @@ struct tag { template struct sender { - using sender_concept = test_std::sender_t; - using index_type = std::integral_constant; + using sender_concept = test_std::sender_t; + using is_basic_sender_tag = void; + using index_type = std::integral_constant; tag t; int value{}; };