24
24
#include " __meta.hpp"
25
25
26
26
#include " ../functional.hpp"
27
+ #include " __utility.hpp"
27
28
28
29
namespace stdexec {
29
30
@@ -78,7 +79,7 @@ namespace stdexec {
78
79
};
79
80
80
81
template <class _Sender >
81
- constexpr bool __is_nothrow_transform_sender () {
82
+ constexpr bool __is_nothrow_transform_sender () noexcept {
82
83
if constexpr (__callable<__sexpr_apply_t , _Sender, __domain::__legacy_customization>) {
83
84
return __nothrow_callable<__sexpr_apply_t , _Sender, __domain::__legacy_customization>;
84
85
} else if constexpr (__domain::__has_default_transform_sender<_Sender>) {
@@ -100,6 +101,43 @@ namespace stdexec {
100
101
}
101
102
} // namespace __domain
102
103
104
+ namespace __detail {
105
+ // /////////////////////////////////////////////////////////////////////////
106
+ template <class _Env , class _Tag >
107
+ using __completion_scheduler_for =
108
+ __meval_or<__call_result_t , __none_such, get_completion_scheduler_t <_Tag>, _Env>;
109
+
110
+ template <class _Env , class _Tag >
111
+ using __completion_domain_for =
112
+ __meval_or<__call_result_t , __none_such, get_domain_t , __completion_scheduler_for<_Env, _Tag>>;
113
+
114
+ // Check the value, error, and stopped channels for completion schedulers.
115
+ // Of the completion schedulers that are known, they must all have compatible
116
+ // domains. This computes that domain, or else returns __none_such if there
117
+ // are no completion schedulers or if they don't specify a domain.
118
+ template <class _Env >
119
+ struct __completion_domain_or_none_
120
+ : __mdefer_<
121
+ __mtransform<
122
+ __mbind_front_q<__completion_domain_for, _Env>,
123
+ __mremove<__none_such, __munique<__msingle_or<__none_such>>>>,
124
+ set_value_t ,
125
+ set_error_t ,
126
+ set_stopped_t > { };
127
+
128
+ template <class _Sender >
129
+ using __completion_domain_or_none = __t <__completion_domain_or_none_<env_of_t <_Sender>>>;
130
+
131
+ template <class _Sender >
132
+ concept __consistent_completion_domains = __mvalid<__completion_domain_or_none, _Sender>;
133
+
134
+ template <class _Sender >
135
+ concept __has_completion_domain = (!same_as<__completion_domain_or_none<_Sender>, __none_such>);
136
+
137
+ template <__has_completion_domain _Sender>
138
+ using __completion_domain_of = __completion_domain_or_none<_Sender>;
139
+ } // namespace __detail
140
+
103
141
struct default_domain {
104
142
default_domain () = default ;
105
143
@@ -159,43 +197,6 @@ namespace stdexec {
159
197
}
160
198
};
161
199
162
- // ///////////////////////////////////////////////////////////////////////////
163
- namespace __detail {
164
- template <class _Env , class _Tag >
165
- using __completion_scheduler_for =
166
- __meval_or<__call_result_t , __none_such, get_completion_scheduler_t <_Tag>, _Env>;
167
-
168
- template <class _Env , class _Tag >
169
- using __completion_domain_for =
170
- __meval_or<__call_result_t , __none_such, get_domain_t , __completion_scheduler_for<_Env, _Tag>>;
171
-
172
- // Check the value, error, and stopped channels for completion schedulers.
173
- // Of the completion schedulers that are known, they must all have compatible
174
- // domains. This computes that domain, or else returns __none_such if there
175
- // are no completion schedulers or if they don't specify a domain.
176
- template <class _Env >
177
- struct __completion_domain_or_none_
178
- : __mdefer_<
179
- __mtransform<
180
- __mbind_front_q<__completion_domain_for, _Env>,
181
- __mremove<__none_such, __munique<__msingle_or<__none_such>>>>,
182
- set_value_t ,
183
- set_error_t ,
184
- set_stopped_t > { };
185
-
186
- template <class _Sender >
187
- using __completion_domain_or_none = __t <__completion_domain_or_none_<env_of_t <_Sender>>>;
188
-
189
- template <class _Sender >
190
- concept __consistent_completion_domains = __mvalid<__completion_domain_or_none, _Sender>;
191
-
192
- template <class _Sender >
193
- concept __has_completion_domain = (!same_as<__completion_domain_or_none<_Sender>, __none_such>);
194
-
195
- template <__has_completion_domain _Sender>
196
- using __completion_domain_of = __completion_domain_or_none<_Sender>;
197
- } // namespace __detail
198
-
199
200
// ///////////////////////////////////////////////////////////////////////////
200
201
// ! Function object implementing `get-domain-early(snd)`
201
202
// ! from [exec.snd.general] item 3.9. It is the first well-formed expression of
@@ -252,22 +253,35 @@ namespace stdexec {
252
253
template <class _Sender , class _Env >
253
254
using __late_domain_of_t = __call_result_t <__get_late_domain_t , _Sender, _Env>;
254
255
255
- namespace __domain {
256
- struct __common_domain_fn {
257
- static auto __common_domain () noexcept -> default_domain {
258
- return {};
259
- }
256
+ // ///////////////////////////////////////////////////////////////////////////
257
+ // dependent_domain
258
+ struct dependent_domain {
259
+ // defined in __transform_sender.hpp
260
+ template <class _Sender , class _Env >
261
+ static constexpr auto __is_nothrow_transform_sender () noexcept -> bool;
260
262
261
- template <class _Domain , class ... _OtherDomains>
262
- requires __all_of<_Domain, _OtherDomains...>
263
- static auto __common_domain (_Domain __domain, _OtherDomains...) noexcept -> _Domain {
264
- return static_cast <_Domain&&>(__domain);
265
- }
263
+ // defined in __transform_sender.hpp
264
+ template <sender_expr _Sender, class _Env >
265
+ requires same_as<__early_domain_of_t <_Sender>, dependent_domain>
266
+ STDEXEC_ATTRIBUTE ((always_inline))
267
+ decltype (auto )
268
+ transform_sender (_Sender&& __sndr, const _Env& __env) const
269
+ noexcept (__is_nothrow_transform_sender<_Sender, _Env>());
270
+ };
266
271
272
+ namespace __domain {
273
+ struct __common_domain_fn {
267
274
template <class ... _Domains>
268
- static auto __common_domain (_Domains...) noexcept //
269
- -> __if_c<__one_of<dependent_domain, _Domains...>, dependent_domain, __none_such> {
270
- return {};
275
+ static auto __common_domain (_Domains...) noexcept {
276
+ if constexpr (sizeof ...(_Domains) == 0 ) {
277
+ return default_domain ();
278
+ } else if constexpr (__one_of<dependent_domain, _Domains...>) {
279
+ return dependent_domain ();
280
+ } else if constexpr (stdexec::__mvalid<std::common_type_t , _Domains...>) {
281
+ return std::common_type_t <_Domains...>();
282
+ } else {
283
+ return __none_such ();
284
+ }
271
285
}
272
286
273
287
auto operator ()(__ignore, __ignore, const auto &... __sndrs) const noexcept {
0 commit comments