xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__continues_on.hpp (revision 36137e09614746b13603b5fbae79e6f70819c46b)
1f083bc1aSPatrick Williams /*
2f083bc1aSPatrick Williams  * Copyright (c) 2021-2024 NVIDIA Corporation
3f083bc1aSPatrick Williams  *
4f083bc1aSPatrick Williams  * Licensed under the Apache License Version 2.0 with LLVM Exceptions
5f083bc1aSPatrick Williams  * (the "License"); you may not use this file except in compliance with
6f083bc1aSPatrick Williams  * the License. You may obtain a copy of the License at
7f083bc1aSPatrick Williams  *
8f083bc1aSPatrick Williams  *   https://llvm.org/LICENSE.txt
9f083bc1aSPatrick Williams  *
10f083bc1aSPatrick Williams  * Unless required by applicable law or agreed to in writing, software
11f083bc1aSPatrick Williams  * distributed under the License is distributed on an "AS IS" BASIS,
12f083bc1aSPatrick Williams  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f083bc1aSPatrick Williams  * See the License for the specific language governing permissions and
14f083bc1aSPatrick Williams  * limitations under the License.
15f083bc1aSPatrick Williams  */
16f083bc1aSPatrick Williams #pragma once
17f083bc1aSPatrick Williams 
18f083bc1aSPatrick Williams #include "__execution_fwd.hpp"
19f083bc1aSPatrick Williams 
20f083bc1aSPatrick Williams // include these after __execution_fwd.hpp
21f083bc1aSPatrick Williams #include "__basic_sender.hpp"
22f083bc1aSPatrick Williams #include "__concepts.hpp"
23f083bc1aSPatrick Williams #include "__env.hpp"
24f083bc1aSPatrick Williams #include "__meta.hpp"
25f083bc1aSPatrick Williams #include "__schedule_from.hpp"
26f083bc1aSPatrick Williams #include "__schedulers.hpp"
27f083bc1aSPatrick Williams #include "__sender_adaptor_closure.hpp"
28f083bc1aSPatrick Williams #include "__sender_introspection.hpp"
29f083bc1aSPatrick Williams #include "__senders.hpp"
30f083bc1aSPatrick Williams #include "__tag_invoke.hpp"
31f083bc1aSPatrick Williams #include "__transform_sender.hpp"
32f083bc1aSPatrick Williams #include "__type_traits.hpp"
33f083bc1aSPatrick Williams 
34f083bc1aSPatrick Williams #include <utility>
35f083bc1aSPatrick Williams 
36f083bc1aSPatrick Williams namespace stdexec
37f083bc1aSPatrick Williams {
38f083bc1aSPatrick Williams /////////////////////////////////////////////////////////////////////////////
39f083bc1aSPatrick Williams // [execution.senders.adaptors.continues_on]
40f083bc1aSPatrick Williams namespace __continues_on
41f083bc1aSPatrick Williams {
42f083bc1aSPatrick Williams using __schfr::__environ;
43f083bc1aSPatrick Williams 
44f083bc1aSPatrick Williams template <class _Env>
45f083bc1aSPatrick Williams using __scheduler_t = __result_of<get_completion_scheduler<set_value_t>, _Env>;
46f083bc1aSPatrick Williams 
47f083bc1aSPatrick Williams template <class _Sender>
48f083bc1aSPatrick Williams using __lowered_t = //
49f083bc1aSPatrick Williams     __result_of<schedule_from, __scheduler_t<__data_of<_Sender>>,
50f083bc1aSPatrick Williams                 __child_of<_Sender>>;
51f083bc1aSPatrick Williams 
52f083bc1aSPatrick Williams struct continues_on_t
53f083bc1aSPatrick Williams {
54f083bc1aSPatrick Williams     template <sender _Sender, scheduler _Scheduler>
operator ()stdexec::__continues_on::continues_on_t55*36137e09SPatrick Williams     auto operator()(_Sender&& __sndr, _Scheduler&& __sched) const
56*36137e09SPatrick Williams         -> __well_formed_sender auto
57f083bc1aSPatrick Williams     {
58f083bc1aSPatrick Williams         auto __domain = __get_early_domain(__sndr);
59f083bc1aSPatrick Williams         using _Env = __t<__environ<__id<__decay_t<_Scheduler>>>>;
60f083bc1aSPatrick Williams         return stdexec::transform_sender(
61f083bc1aSPatrick Williams             __domain, __make_sexpr<continues_on_t>(
62f083bc1aSPatrick Williams                           _Env{{static_cast<_Scheduler&&>(__sched)}},
63f083bc1aSPatrick Williams                           static_cast<_Sender&&>(__sndr)));
64f083bc1aSPatrick Williams     }
65f083bc1aSPatrick Williams 
66f083bc1aSPatrick Williams     template <scheduler _Scheduler>
67f083bc1aSPatrick Williams     STDEXEC_ATTRIBUTE((always_inline))
operator ()stdexec::__continues_on::continues_on_t68f083bc1aSPatrick Williams     auto operator()(_Scheduler&& __sched) const
69f083bc1aSPatrick Williams         -> __binder_back<continues_on_t, __decay_t<_Scheduler>>
70f083bc1aSPatrick Williams     {
71f083bc1aSPatrick Williams         return {{static_cast<_Scheduler&&>(__sched)}, {}, {}};
72f083bc1aSPatrick Williams     }
73f083bc1aSPatrick Williams 
74f083bc1aSPatrick Williams     //////////////////////////////////////////////////////////////////////////////////////////////
75f083bc1aSPatrick Williams     using _Env = __0;
76f083bc1aSPatrick Williams     using _Sender = __1;
77f083bc1aSPatrick Williams     using __legacy_customizations_t = //
78f083bc1aSPatrick Williams         __types<tag_invoke_t(continues_on_t,
79f083bc1aSPatrick Williams                              get_completion_scheduler_t<set_value_t>(
80f083bc1aSPatrick Williams                                  get_env_t(const _Sender&)),
81f083bc1aSPatrick Williams                              _Sender,
82f083bc1aSPatrick Williams                              get_completion_scheduler_t<set_value_t>(_Env)),
83f083bc1aSPatrick Williams                 tag_invoke_t(continues_on_t, _Sender,
84f083bc1aSPatrick Williams                              get_completion_scheduler_t<set_value_t>(_Env))>;
85f083bc1aSPatrick Williams 
86f083bc1aSPatrick Williams     template <class _Env>
__transform_sender_fnstdexec::__continues_on::continues_on_t87f083bc1aSPatrick Williams     static auto __transform_sender_fn(const _Env&)
88f083bc1aSPatrick Williams     {
89f083bc1aSPatrick Williams         return [&]<class _Data, class _Child>(__ignore, _Data&& __data,
90f083bc1aSPatrick Williams                                               _Child&& __child) {
91f083bc1aSPatrick Williams             auto __sched = get_completion_scheduler<set_value_t>(__data);
92f083bc1aSPatrick Williams             return schedule_from(std::move(__sched),
93f083bc1aSPatrick Williams                                  static_cast<_Child&&>(__child));
94f083bc1aSPatrick Williams         };
95f083bc1aSPatrick Williams     }
96f083bc1aSPatrick Williams 
97f083bc1aSPatrick Williams     template <class _Sender, class _Env>
transform_senderstdexec::__continues_on::continues_on_t98f083bc1aSPatrick Williams     static auto transform_sender(_Sender&& __sndr, const _Env& __env)
99f083bc1aSPatrick Williams     {
100f083bc1aSPatrick Williams         return __sexpr_apply(static_cast<_Sender&&>(__sndr),
101f083bc1aSPatrick Williams                              __transform_sender_fn(__env));
102f083bc1aSPatrick Williams     }
103f083bc1aSPatrick Williams };
104f083bc1aSPatrick Williams 
105f083bc1aSPatrick Williams struct __continues_on_impl : __sexpr_defaults
106f083bc1aSPatrick Williams {
107f083bc1aSPatrick Williams     static constexpr auto get_attrs = //
108f083bc1aSPatrick Williams         []<class _Data, class _Child>(
109f083bc1aSPatrick Williams             const _Data& __data,
110f083bc1aSPatrick Williams             const _Child& __child) noexcept -> decltype(auto) {
111f083bc1aSPatrick Williams         return __env::__join(__data, stdexec::get_env(__child));
112f083bc1aSPatrick Williams     };
113f083bc1aSPatrick Williams 
114f083bc1aSPatrick Williams     static constexpr auto get_completion_signatures = //
115f083bc1aSPatrick Williams         []<class _Sender>(_Sender&&) noexcept         //
116f083bc1aSPatrick Williams         -> __completion_signatures_of_t<              //
117f083bc1aSPatrick Williams             transform_sender_result_t<default_domain, _Sender, empty_env>> {};
118f083bc1aSPatrick Williams };
119f083bc1aSPatrick Williams } // namespace __continues_on
120f083bc1aSPatrick Williams 
121f083bc1aSPatrick Williams using __continues_on::continues_on_t;
122f083bc1aSPatrick Williams inline constexpr continues_on_t continues_on{};
123f083bc1aSPatrick Williams 
124f083bc1aSPatrick Williams using transfer_t = continues_on_t;
125f083bc1aSPatrick Williams inline constexpr continues_on_t transfer{};
126f083bc1aSPatrick Williams 
127f083bc1aSPatrick Williams using continue_on_t = continues_on_t;
128f083bc1aSPatrick Williams inline constexpr continues_on_t continue_on{};
129f083bc1aSPatrick Williams 
130f083bc1aSPatrick Williams template <>
131f083bc1aSPatrick Williams struct __sexpr_impl<continues_on_t> : __continues_on::__continues_on_impl
132f083bc1aSPatrick Williams {};
133f083bc1aSPatrick Williams } // namespace stdexec
134