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 "__execution_fwd.hpp"
19
20 // include these after __execution_fwd.hpp
21 #include "__basic_sender.hpp"
22 #include "__concepts.hpp"
23 #include "__continues_on.hpp"
24 #include "__domain.hpp"
25 #include "__env.hpp"
26 #include "__just.hpp"
27 #include "__meta.hpp"
28 #include "__schedule_from.hpp"
29 #include "__schedulers.hpp"
30 #include "__sender_introspection.hpp"
31 #include "__tag_invoke.hpp"
32 #include "__transform_sender.hpp"
33 #include "__tuple.hpp"
34
35 STDEXEC_PRAGMA_PUSH()
36 STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces")
37
38 namespace stdexec
39 {
40 /////////////////////////////////////////////////////////////////////////////
41 // [execution.senders.transfer_just]
42 namespace __transfer_just
43 {
44 // This is a helper for finding legacy cusutomizations of transfer_just.
__transfer_just_tag_invoke()45 inline auto __transfer_just_tag_invoke()
46 {
47 return []<class... _Ts>(
48 _Ts&&... __ts) -> tag_invoke_result_t<transfer_just_t, _Ts...> {
49 return tag_invoke(transfer_just, static_cast<_Ts&&>(__ts)...);
50 };
51 }
52
53 template <class _Env>
__make_transform_fn(const _Env &)54 auto __make_transform_fn(const _Env&)
55 {
56 return [&]<class _Scheduler, class... _Values>(_Scheduler&& __sched,
57 _Values&&... __vals) {
58 return continues_on(just(static_cast<_Values&&>(__vals)...),
59 static_cast<_Scheduler&&>(__sched));
60 };
61 }
62
63 template <class _Env>
__transform_sender_fn(const _Env & __env)64 auto __transform_sender_fn(const _Env& __env)
65 {
66 return [&]<class _Data>(__ignore, _Data&& __data) {
67 return __data.apply(__make_transform_fn(__env),
68 static_cast<_Data&&>(__data));
69 };
70 }
71
72 struct __legacy_customization_fn
73 {
74 template <class _Data>
operator ()stdexec::__transfer_just::__legacy_customization_fn75 auto operator()(_Data&& __data) const
76 -> decltype(__data.apply(__transfer_just_tag_invoke(),
77 static_cast<_Data&&>(__data)))
78 {
79 return __data.apply(__transfer_just_tag_invoke(),
80 static_cast<_Data&&>(__data));
81 }
82 };
83
84 struct transfer_just_t
85 {
86 using _Data = __0;
87 using __legacy_customizations_t = //
88 __types<__legacy_customization_fn(_Data)>;
89
90 template <scheduler _Scheduler, __movable_value... _Values>
operator ()stdexec::__transfer_just::transfer_just_t91 auto operator()(_Scheduler&& __sched, _Values&&... __vals) const
92 -> __well_formed_sender auto
93 {
94 auto __domain = query_or(get_domain, __sched, default_domain());
95 return stdexec::transform_sender(
96 __domain, __make_sexpr<transfer_just_t>(
97 __tuple{static_cast<_Scheduler&&>(__sched),
98 static_cast<_Values&&>(__vals)...}));
99 }
100
101 template <class _Sender, class _Env>
transform_senderstdexec::__transfer_just::transfer_just_t102 static auto transform_sender(_Sender&& __sndr, const _Env& __env)
103 {
104 return __sexpr_apply(static_cast<_Sender&&>(__sndr),
105 __transform_sender_fn(__env));
106 }
107 };
108
__make_env_fn()109 inline auto __make_env_fn() noexcept
110 {
111 return []<class _Scheduler>(const _Scheduler& __sched,
112 const auto&...) noexcept {
113 using _Env = __t<__schfr::__environ<__id<_Scheduler>>>;
114 return _Env{__sched};
115 };
116 }
117
118 struct __transfer_just_impl : __sexpr_defaults
119 {
120 static constexpr auto get_attrs = //
121 []<class _Data>(const _Data& __data) noexcept {
122 return __data.apply(__make_env_fn(), __data);
123 };
124
125 static constexpr auto get_completion_signatures = //
126 []<class _Sender>(_Sender&&) noexcept //
127 -> __completion_signatures_of_t< //
128 transform_sender_result_t<default_domain, _Sender, empty_env>> {};
129 };
130 } // namespace __transfer_just
131
132 using __transfer_just::transfer_just_t;
133 inline constexpr transfer_just_t transfer_just{};
134
135 template <>
136 struct __sexpr_impl<transfer_just_t> : __transfer_just::__transfer_just_impl
137 {};
138 } // namespace stdexec
139
140 STDEXEC_PRAGMA_POP()
141