From 3b9b901df79a27347c920fa155adf85b26543a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Fri, 30 Aug 2024 20:21:09 +0100 Subject: [PATCH 1/5] added get_domain_early --- .../execution26/detail/get_domain_early.hpp | 40 +++++++++++++ .../execution26/tests/exec-snd-expos.pass.cpp | 59 ++++++++++++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 include/beman/execution26/detail/get_domain_early.hpp diff --git a/include/beman/execution26/detail/get_domain_early.hpp b/include/beman/execution26/detail/get_domain_early.hpp new file mode 100644 index 00000000..2ea79d5a --- /dev/null +++ b/include/beman/execution26/detail/get_domain_early.hpp @@ -0,0 +1,40 @@ +// include/beman/execution26/detail/get_domain_early.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_GET_DOMAIN_EARLY +#define INCLUDED_BEMAN_EXECUTION26_DETAIL_GET_DOMAIN_EARLY + +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- + +namespace beman::execution26::detail +{ + template + constexpr auto get_domain_early(Sender const& sender) noexcept + { + if constexpr (requires{ + ::beman::execution26::get_domain( + ::beman::execution26::get_env(sender) + ); + }) + return decltype( + ::beman::execution26::get_domain( + ::beman::execution26::get_env(sender) + ) + ){}; + else if constexpr (requires{ + ::beman::execution26::detail::completion_domain(sender); + }) + return decltype(::beman::execution26::detail::completion_domain(sender)){}; + else + return ::beman::execution26::default_domain{}; + } +} + +// ---------------------------------------------------------------------------- + +#endif diff --git a/src/beman/execution26/tests/exec-snd-expos.pass.cpp b/src/beman/execution26/tests/exec-snd-expos.pass.cpp index cc8dc265..fc432ec1 100644 --- a/src/beman/execution26/tests/exec-snd-expos.pass.cpp +++ b/src/beman/execution26/tests/exec-snd-expos.pass.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -332,6 +333,17 @@ namespace auto operator== (scheduler const&) const -> bool = default; }; + template <> + struct env + { + template + auto query(test_std::get_completion_scheduler_t const&) const noexcept + -> scheduler + { + return {}; + } + }; + template <> struct env { @@ -407,8 +419,52 @@ namespace assert(result2.default_value == 74); } + auto test_get_domain_early() -> void + { + struct plain_sender + { + using sender_concept = test_std::sender_t; + }; + static_assert(test_std::sender); + static_assert(std::same_as< + test_std::default_domain, + decltype(test_detail::get_domain_early(plain_sender{})) + >); + + namespace cd = completion_domain; + static_assert(test_std::sender>); + static_assert(std::same_as< + cd::domain, + decltype(test_detail::get_domain_early(cd::sender{})) + >); + + struct sender_with_domain + { + using sender_concept = test_std::sender_t; + struct domain {}; + struct env + { + auto query(test_std::get_domain_t const&) const noexcept -> domain { return {}; } + }; + auto get_env() const noexcept -> env { return {}; } + }; + static_assert(test_std::sender); + static_assert(std::same_as< + sender_with_domain::env, + decltype(test_std::get_env(sender_with_domain{})) + >); + static_assert(std::same_as< + sender_with_domain::domain, + decltype(test_std::get_domain(sender_with_domain::env{})) + >); + static_assert(std::same_as< + sender_with_domain::domain, + decltype(test_detail::get_domain_early(sender_with_domain{})) + >); + } + template - auto test_get_domain_late(auto sender, auto env) + auto test_get_domain_late(auto sender, auto env) -> void { static_assert(test_std::sender); static_assert(test_detail::queryable); @@ -1186,6 +1242,7 @@ auto main() -> int test_sched_env(); test_completion_domain(); test_query_with_default(); + test_get_domain_early(); test_get_domain_late(); test_default_impls(); test_impls_for(); From ea62dbfafd47997811bf57ccfbcabde61d6b6369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Sat, 31 Aug 2024 01:03:35 +0100 Subject: [PATCH 2/5] added make_sender --- .../beman/execution26/detail/make_sender.hpp | 35 +++++++++++++++++++ .../execution26/tests/exec-snd-expos.pass.cpp | 27 ++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 include/beman/execution26/detail/make_sender.hpp diff --git a/include/beman/execution26/detail/make_sender.hpp b/include/beman/execution26/detail/make_sender.hpp new file mode 100644 index 00000000..d3394ab6 --- /dev/null +++ b/include/beman/execution26/detail/make_sender.hpp @@ -0,0 +1,35 @@ +// include/beman/execution26/detail/make_sender.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_MAKE_SENDER +#define INCLUDED_BEMAN_EXECUTION26_DETAIL_MAKE_SENDER + +#include +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- + +namespace beman::execution26::detail +{ + struct make_sender_empty {}; + + template + requires ::std::semiregular + && ::beman::execution26::detail::movable_value + && (::beman::execution26::sender && ...) + constexpr auto make_sender(Tag tag, Data&& data, Child&&... child) + { + return ::beman::execution26::detail::basic_sender< + Tag, ::std::decay_t, ::std::decay_t... + >{tag, ::std::forward(data), child...}; + } +} + +// ---------------------------------------------------------------------------- + +#endif diff --git a/src/beman/execution26/tests/exec-snd-expos.pass.cpp b/src/beman/execution26/tests/exec-snd-expos.pass.cpp index fc432ec1..f513a058 100644 --- a/src/beman/execution26/tests/exec-snd-expos.pass.cpp +++ b/src/beman/execution26/tests/exec-snd-expos.pass.cpp @@ -1,6 +1,7 @@ // src/beman/execution26/tests/exe-snd-expos.pass.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include #include #include @@ -1231,6 +1232,31 @@ namespace basic_sender::indices_for >); } + + template + auto test_make_sender() -> void + { + { + auto sender{test_detail::make_sender(tag{}, {})}; + static_assert(test_std::sender); + } + { + auto sender{test_detail::make_sender(tag{}, int{17})}; + static_assert(test_std::sender); + static_assert(std::same_as, decltype(sender)>); + } + { + static_assert(not requires{ test_detail::make_sender(tag{}, int{17}, T()); }); + } + { + auto sender{test_detail::make_sender(tag{}, int{17}, sender0{})}; + static_assert(test_std::sender); + static_assert(std::same_as< + test_detail::basic_sender, + decltype(sender) + >); + } + } } auto main() -> int @@ -1259,4 +1285,5 @@ auto main() -> int test_basic_operation(); test_completion_signatures_for(); test_basic_sender(); + test_make_sender(); } \ No newline at end of file From e9fd69c369d29aca0f609136ff386f929fa4aaae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Sat, 31 Aug 2024 01:44:30 +0100 Subject: [PATCH 3/5] added sender_adaptor_closure --- .../detail/sender_adaptor_closure.hpp | 44 +++++++++++++++++++ .../execution26/tests/exec-snd-expos.pass.cpp | 1 + .../execution26/tests/execution-syn.pass.cpp | 39 ++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 include/beman/execution26/detail/sender_adaptor_closure.hpp diff --git a/include/beman/execution26/detail/sender_adaptor_closure.hpp b/include/beman/execution26/detail/sender_adaptor_closure.hpp new file mode 100644 index 00000000..be52c9ba --- /dev/null +++ b/include/beman/execution26/detail/sender_adaptor_closure.hpp @@ -0,0 +1,44 @@ +// include/beman/execution26/detail/sender_adaptor_closure.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_SENDER_ADAPTOR_CLOSURE +#define INCLUDED_BEMAN_EXECUTION26_DETAIL_SENDER_ADAPTOR_CLOSURE + +#include +#include +#include + +// ---------------------------------------------------------------------------- + +namespace beman::execution26::detail::pipeable +{ + struct sender_adaptor_closure_base {}; +} + +namespace beman::execution26 +{ + template + struct sender_adaptor_closure + : ::beman::execution26::detail::pipeable::sender_adaptor_closure_base + { + }; +} + +namespace beman::execution26::detail::pipeable +{ + template <::beman::execution26::sender Sender, typename Adaptor> + requires (not ::beman::execution26::sender) + && ::std::derived_from> + && requires(Sender&& sender, Adaptor const& adaptor) + { + { adaptor(::std::forward(sender)) } -> ::beman::execution26::sender; + } + auto operator| (Sender&& sender, Adaptor const& adaptor) + { + return adaptor(::std::forward(sender)); + } +} + +// ---------------------------------------------------------------------------- + +#endif diff --git a/src/beman/execution26/tests/exec-snd-expos.pass.cpp b/src/beman/execution26/tests/exec-snd-expos.pass.cpp index f513a058..7f402fb8 100644 --- a/src/beman/execution26/tests/exec-snd-expos.pass.cpp +++ b/src/beman/execution26/tests/exec-snd-expos.pass.cpp @@ -508,6 +508,7 @@ namespace { using sender_concept = test_std::sender_t; }; + static_assert(test_std::sender); test_get_domain_late(no_domain_sender{}, test_std::empty_env{}); struct scheduler_env diff --git a/src/beman/execution26/tests/execution-syn.pass.cpp b/src/beman/execution26/tests/execution-syn.pass.cpp index cce6850a..31ef5529 100644 --- a/src/beman/execution26/tests/execution-syn.pass.cpp +++ b/src/beman/execution26/tests/execution-syn.pass.cpp @@ -1,6 +1,7 @@ // src/beman/execution26/tests/execution-syn.pass.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include #include #include @@ -20,6 +21,7 @@ namespace { + auto use(auto&&) -> void {} struct scheduler { struct env @@ -377,6 +379,42 @@ namespace static_assert(not test_detail::decays_to); static_assert(not test_detail::decays_to); } + + template + struct adapted_sender + { + using sender_concept = test_std::sender_t; + }; + + struct closure_t + : test_std::sender_adaptor_closure + { + template + auto operator()(Sender&&) const -> adapted_sender + { + return {}; + } + }; + constexpr closure_t closure{}; + + auto test_sender_adaptor_closure() -> void + { + use(test_std::sender_adaptor_closure{}); + struct sender + { + using sender_concept = test_std::sender_t; + }; + static_assert(test_std::sender); + + static_assert(test_std::sender>); + static_assert(not test_std::sender); + + auto direct{closure(sender{})}; + static_assert(std::same_as, decltype(direct)>); + auto via_op{sender{} | closure }; + use(via_op); + static_assert(std::same_as, decltype(via_op)>); + } } auto main() -> int @@ -391,4 +429,5 @@ auto main() -> int test_single_sender(); test_conect_result_t(); test_decays_to(); + test_sender_adaptor_closure(); } From 3d8f1478c7a5686bdfeff49673a0eefff943ee8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Sat, 31 Aug 2024 02:26:39 +0100 Subject: [PATCH 4/5] added sender_adaptor --- .../execution26/detail/sender_adaptor.hpp | 61 +++++++++++++++++++ .../detail/sender_adaptor_closure.hpp | 8 ++- .../execution26/tests/execution-syn.pass.cpp | 34 ++++++++++- 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 include/beman/execution26/detail/sender_adaptor.hpp diff --git a/include/beman/execution26/detail/sender_adaptor.hpp b/include/beman/execution26/detail/sender_adaptor.hpp new file mode 100644 index 00000000..0572b814 --- /dev/null +++ b/include/beman/execution26/detail/sender_adaptor.hpp @@ -0,0 +1,61 @@ +// include/beman/execution26/detail/sender_adaptor.hpp -*-C++-*- +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef INCLUDED_BEMAN_EXECUTION26_DETAIL_SENDER_ADAPTOR +#define INCLUDED_BEMAN_EXECUTION26_DETAIL_SENDER_ADAPTOR + +#include +#include +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- + +namespace beman::execution26::detail +{ + template + struct sender_adaptor + : ::beman::execution26::detail::product_type< + ::std::decay_t, ::std::decay_t, ::std::decay_t...> + , ::beman::execution26::sender_adaptor_closure> + { + template <::beman::execution26::sender Sender> + static auto apply(Sender&& sender, auto&& self) + { + using base_type = ::beman::execution26::detail::product_type< + ::std::decay_t, ::std::decay_t, ::std::decay_t...>; + static constexpr ::beman::execution26::detail::sender_any_t at{}; + if constexpr (requires{ base_type{ at, at, at, at }; }) + { + auto&&[adaptor, arg0, arg1, arg2] = self; + return adaptor(::std::forward(sender), arg0, arg1, arg2); + } + if constexpr (requires{ base_type{ at, at, at }; }) + { + auto&&[adaptor, arg0, arg1] = self; + return adaptor(::std::forward(sender), arg0, arg1); + } + else if constexpr (requires{ base_type{ at, at }; }) + { + auto&&[adaptor, arg0] = self; + return adaptor(::std::forward(sender), arg0); + } + } + template <::beman::execution26::sender Sender> + auto operator()(Sender&& sender) + { + return apply(::std::forward(sender), *this); + } + template <::beman::execution26::sender Sender> + auto operator()(Sender&& sender) const + { + return apply(::std::forward(sender), *this); + } + }; +} + +// ---------------------------------------------------------------------------- + +#endif diff --git a/include/beman/execution26/detail/sender_adaptor_closure.hpp b/include/beman/execution26/detail/sender_adaptor_closure.hpp index be52c9ba..6eb64cb9 100644 --- a/include/beman/execution26/detail/sender_adaptor_closure.hpp +++ b/include/beman/execution26/detail/sender_adaptor_closure.hpp @@ -6,6 +6,7 @@ #include #include +#include #include // ---------------------------------------------------------------------------- @@ -28,12 +29,13 @@ namespace beman::execution26::detail::pipeable { template <::beman::execution26::sender Sender, typename Adaptor> requires (not ::beman::execution26::sender) - && ::std::derived_from> - && requires(Sender&& sender, Adaptor const& adaptor) + && ::std::derived_from<::std::decay_t, + ::beman::execution26::sender_adaptor_closure<::std::decay_t>> + && requires(Sender&& sender, Adaptor&& adaptor) { { adaptor(::std::forward(sender)) } -> ::beman::execution26::sender; } - auto operator| (Sender&& sender, Adaptor const& adaptor) + auto operator| (Sender&& sender, Adaptor&& adaptor) { return adaptor(::std::forward(sender)); } diff --git a/src/beman/execution26/tests/execution-syn.pass.cpp b/src/beman/execution26/tests/execution-syn.pass.cpp index 31ef5529..7a89d617 100644 --- a/src/beman/execution26/tests/execution-syn.pass.cpp +++ b/src/beman/execution26/tests/execution-syn.pass.cpp @@ -1,6 +1,7 @@ // src/beman/execution26/tests/execution-syn.pass.cpp -*-C++-*- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include #include #include @@ -412,7 +413,37 @@ namespace auto direct{closure(sender{})}; static_assert(std::same_as, decltype(direct)>); auto via_op{sender{} | closure }; - use(via_op); + static_assert(std::same_as, decltype(via_op)>); + } + + struct arg_closure_t + { + template + auto operator()(Sender&&, int) const -> adapted_sender + { + return {}; + } + auto operator()(int value) const + { + return test_detail::sender_adaptor{{*this, value}}; + } + }; + constexpr arg_closure_t arg_closure{}; + + auto test_sender_adaptor() -> void + { + struct sender + { + using sender_concept = test_std::sender_t; + }; + static_assert(test_std::sender); + + auto closure{arg_closure(17)}; + static_assert(std::same_as< + test_detail::sender_adaptor, decltype(closure)>); + auto direct{closure(sender{})}; + static_assert(std::same_as, decltype(direct)>); + auto via_op{sender{} | closure }; static_assert(std::same_as, decltype(via_op)>); } } @@ -430,4 +461,5 @@ auto main() -> int test_conect_result_t(); test_decays_to(); test_sender_adaptor_closure(); + test_sender_adaptor(); } From 221a90d9fe9a563eb516255d1e5ab13303055486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dietmar=20K=C3=BChl?= Date: Sat, 31 Aug 2024 02:28:50 +0100 Subject: [PATCH 5/5] added a direct initializer of the empty base --- src/beman/execution26/tests/execution-syn.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/beman/execution26/tests/execution-syn.pass.cpp b/src/beman/execution26/tests/execution-syn.pass.cpp index 7a89d617..a88a3b99 100644 --- a/src/beman/execution26/tests/execution-syn.pass.cpp +++ b/src/beman/execution26/tests/execution-syn.pass.cpp @@ -425,7 +425,7 @@ namespace } auto operator()(int value) const { - return test_detail::sender_adaptor{{*this, value}}; + return test_detail::sender_adaptor{{*this, value}, {}}; } }; constexpr arg_closure_t arg_closure{};