Skip to content

Commit 37fc793

Browse files
authored
change the common domain computation to use std::common_type (#1451)
1 parent c3f90d4 commit 37fc793

File tree

3 files changed

+66
-66
lines changed

3 files changed

+66
-66
lines changed

include/exec/static_thread_pool.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ namespace exec {
261261
}
262262

263263
public:
264-
struct domain {
264+
struct domain : stdexec::default_domain {
265265
// For eager customization
266266
template <sender_expr_for<bulk_t> Sender>
267267
auto transform_sender(Sender&& sndr) const noexcept {

include/stdexec/__detail/__domain.hpp

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "__meta.hpp"
2525

2626
#include "../functional.hpp"
27+
#include "__utility.hpp"
2728

2829
namespace stdexec {
2930

@@ -78,7 +79,7 @@ namespace stdexec {
7879
};
7980

8081
template <class _Sender>
81-
constexpr bool __is_nothrow_transform_sender() {
82+
constexpr bool __is_nothrow_transform_sender() noexcept {
8283
if constexpr (__callable<__sexpr_apply_t, _Sender, __domain::__legacy_customization>) {
8384
return __nothrow_callable<__sexpr_apply_t, _Sender, __domain::__legacy_customization>;
8485
} else if constexpr (__domain::__has_default_transform_sender<_Sender>) {
@@ -100,6 +101,43 @@ namespace stdexec {
100101
}
101102
} // namespace __domain
102103

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+
103141
struct default_domain {
104142
default_domain() = default;
105143

@@ -159,43 +197,6 @@ namespace stdexec {
159197
}
160198
};
161199

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-
199200
/////////////////////////////////////////////////////////////////////////////
200201
//! Function object implementing `get-domain-early(snd)`
201202
//! from [exec.snd.general] item 3.9. It is the first well-formed expression of
@@ -252,22 +253,35 @@ namespace stdexec {
252253
template <class _Sender, class _Env>
253254
using __late_domain_of_t = __call_result_t<__get_late_domain_t, _Sender, _Env>;
254255

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;
260262

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+
};
266271

272+
namespace __domain {
273+
struct __common_domain_fn {
267274
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+
}
271285
}
272286

273287
auto operator()(__ignore, __ignore, const auto&... __sndrs) const noexcept {

include/stdexec/__detail/__transform_sender.hpp

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,6 @@ STDEXEC_PRAGMA_PUSH()
3131
STDEXEC_PRAGMA_IGNORE_EDG(type_qualifiers_ignored_on_reference)
3232

3333
namespace stdexec {
34-
/////////////////////////////////////////////////////////////////////////////
35-
// dependent_domain
36-
struct dependent_domain {
37-
template <class _Sender, class _Env>
38-
static constexpr auto __is_nothrow_transform_sender() noexcept -> bool;
39-
40-
template <sender_expr _Sender, class _Env>
41-
requires same_as<__early_domain_of_t<_Sender>, dependent_domain>
42-
STDEXEC_ATTRIBUTE((always_inline))
43-
decltype(auto)
44-
transform_sender(_Sender&& __sndr, const _Env& __env) const
45-
noexcept(__is_nothrow_transform_sender<_Sender, _Env>());
46-
};
47-
4834
/////////////////////////////////////////////////////////////////////////////
4935
// [execution.transform_sender]
5036
namespace __domain {

0 commit comments

Comments
 (0)