xref: /openbmc/sdbusplus/include/sdbusplus/async/stdexec/__detail/__start_detached.hpp (revision 5cee91570368554a7fcbbd9418f65efda449fa70)
1 /*
2  * Copyright (c) 2021-2024 NVIDIA Corporation
3  *
4  * Licensed under the Apache License Version 2.0 with LLVM Exceptions
5  * (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  *
8  *   https://llvm.org/LICENSE.txt
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "__cpo.hpp"
19 #include "__env.hpp"
20 #include "__execution_fwd.hpp"
21 #include "__meta.hpp"
22 #include "__receivers.hpp"
23 #include "__senders.hpp"
24 #include "__submit.hpp"
25 #include "__transform_sender.hpp"
26 #include "__type_traits.hpp"
27 
28 namespace stdexec
29 {
30 /////////////////////////////////////////////////////////////////////////////
31 // [execution.senders.consumer.start_detached]
32 namespace __start_detached
33 {
34 template <class _EnvId>
35 struct __detached_receiver
36 {
37     using _Env = stdexec::__t<_EnvId>;
38 
39     struct __t
40     {
41         using receiver_concept = receiver_t;
42         using __id = __detached_receiver;
43         STDEXEC_ATTRIBUTE((no_unique_address))
44         _Env __env_;
45 
46         template <class... _As>
set_valuestdexec::__start_detached::__detached_receiver::__t47         void set_value(_As&&...) noexcept
48         {}
49 
50         template <class _Error>
set_errorstdexec::__start_detached::__detached_receiver::__t51         [[noreturn]] void set_error(_Error&&) noexcept
52         {
53             std::terminate();
54         }
55 
set_stoppedstdexec::__start_detached::__detached_receiver::__t56         void set_stopped() noexcept {}
57 
get_envstdexec::__start_detached::__detached_receiver::__t58         auto get_env() const noexcept -> const _Env&
59         {
60             // BUGBUG NOT TO SPEC
61             return __env_;
62         }
63     };
64 };
65 
66 template <class _Env = empty_env>
67 using __detached_receiver_t = __t<__detached_receiver<__id<__decay_t<_Env>>>>;
68 
69 struct start_detached_t
70 {
71     template <sender_in<__root_env> _Sender>
72         requires __callable<apply_sender_t, __early_domain_of_t<_Sender>,
73                             start_detached_t, _Sender>
operator ()stdexec::__start_detached::start_detached_t74     void operator()(_Sender&& __sndr) const
75     {
76         auto __domain = __get_early_domain(__sndr);
77         stdexec::apply_sender(__domain, *this, static_cast<_Sender&&>(__sndr));
78     }
79 
80     template <class _Env, sender_in<__as_root_env_t<_Env>> _Sender>
81         requires __callable<apply_sender_t,
82                             __late_domain_of_t<_Sender, __as_root_env_t<_Env>>,
83                             start_detached_t, _Sender, __as_root_env_t<_Env>>
operator ()stdexec::__start_detached::start_detached_t84     void operator()(_Sender&& __sndr, _Env&& __env) const
85     {
86         auto __domain = __get_late_domain(__sndr, __env);
87         stdexec::apply_sender(__domain, *this, static_cast<_Sender&&>(__sndr),
88                               __as_root_env(static_cast<_Env&&>(__env)));
89     }
90 
91     using _Sender = __0;
92     using __legacy_customizations_t =
93         __types<tag_invoke_t(start_detached_t,
94                              get_completion_scheduler_t<set_value_t>(
95                                  get_env_t(const _Sender&)),
96                              _Sender),
97                 tag_invoke_t(start_detached_t, _Sender)>;
98 
99     template <class _Sender, class _Env = __root_env>
100         requires sender_to<_Sender, __detached_receiver_t<_Env>>
apply_senderstdexec::__start_detached::start_detached_t101     void apply_sender(_Sender&& __sndr, _Env&& __env = {}) const
102     {
103         __submit(static_cast<_Sender&&>(__sndr),
104                  __detached_receiver_t<_Env>{static_cast<_Env&&>(__env)});
105     }
106 };
107 } // namespace __start_detached
108 
109 using __start_detached::start_detached_t;
110 inline constexpr start_detached_t start_detached{};
111 } // namespace stdexec
112