Skip to content

Commit d8d63a7

Browse files
committed
try to avoid gcc concept recursion
1 parent 92cf09d commit d8d63a7

2 files changed

Lines changed: 32 additions & 24 deletions

File tree

include/stdexec/__detail/__env.hpp

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -342,35 +342,43 @@ namespace stdexec {
342342
/////////////////////////////////////////////////////////////////////////////
343343
namespace __get_env {
344344
template <class _EnvProvider>
345-
concept __has_get_env = requires(const _EnvProvider& __env_provider) {
346-
__env_provider.get_env();
347-
};
345+
using __get_env_member_t = decltype(__declval<_EnvProvider>().get_env());
346+
347+
template <class _EnvProvider>
348+
concept __has_get_env = __mvalid<__get_env_member_t, _EnvProvider>;
348349

349350
// For getting an execution environment from a receiver or the attributes from a sender.
350351
struct get_env_t {
352+
private:
351353
template <class _EnvProvider>
352-
requires __has_get_env<_EnvProvider>
353-
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
354-
constexpr auto operator()(const _EnvProvider& __env_provider) const noexcept
355-
-> decltype(__env_provider.get_env()) {
356-
static_assert(queryable<decltype(__env_provider.get_env())>);
357-
static_assert(noexcept(__env_provider.get_env()), "get_env() members must be noexcept");
358-
return __env_provider.get_env();
359-
}
360-
361-
template <class _EnvProvider>
362-
requires(!__has_get_env<_EnvProvider>) && tag_invocable<get_env_t, const _EnvProvider&>
363-
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
364-
constexpr auto operator()(const _EnvProvider& __env_provider) const noexcept
365-
-> tag_invoke_result_t<get_env_t, const _EnvProvider&> {
366-
static_assert(queryable<tag_invoke_result_t<get_env_t, const _EnvProvider&>>);
367-
static_assert(nothrow_tag_invocable<get_env_t, const _EnvProvider&>);
368-
return tag_invoke(*this, __env_provider);
354+
static constexpr auto __get_declfn() noexcept {
355+
constexpr __declfn_t<_EnvProvider> __env_provider{};
356+
if constexpr (__has_get_env<_EnvProvider>) {
357+
using __result_t = __get_env_member_t<_EnvProvider>;
358+
static_assert(noexcept(__env_provider().get_env()), "get_env() members must be noexcept");
359+
return __declfn<__result_t>();
360+
} else if constexpr (tag_invocable<get_env_t, const _EnvProvider&>) {
361+
using __result_t = tag_invoke_result_t<get_env_t, const _EnvProvider&>;
362+
constexpr bool __is_nothrow = nothrow_tag_invocable<get_env_t, const _EnvProvider&>;
363+
static_assert(__is_nothrow, "get_env tag_invoke overloads must be noexcept");
364+
return __declfn<__result_t>();
365+
} else {
366+
return __declfn<env<>>();
367+
}
369368
}
370369

370+
public:
371+
template <class _EnvProvider, auto _DeclFn = __get_declfn<_EnvProvider>()>
371372
STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)
372-
constexpr auto operator()(__ignore) const noexcept -> env<> {
373-
return {};
373+
constexpr auto
374+
operator()(const _EnvProvider& __env_provider) const noexcept -> decltype(_DeclFn()) {
375+
if constexpr (__has_get_env<_EnvProvider>) {
376+
return __env_provider.get_env();
377+
} else if constexpr (tag_invocable<get_env_t, const _EnvProvider&>) {
378+
return tag_invoke(*this, __env_provider);
379+
} else {
380+
return env<>{};
381+
}
374382
}
375383
};
376384
} // namespace __get_env

include/stdexec/__detail/__senders.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ namespace stdexec {
262262

263263
if constexpr (__with_static_member<_TfxSender, _Receiver>) {
264264
auto&& __tfx_sndr = transform_sender(static_cast<_Sender&&>(__sndr), __env);
265-
return __tfx_sndr
266-
.connect(static_cast<_TfxSender&&>(__tfx_sndr), static_cast<_Receiver&&>(__rcvr));
265+
return STDEXEC_REMOVE_REFERENCE(_TfxSender)::connect(
266+
static_cast<_TfxSender&&>(__tfx_sndr), static_cast<_Receiver&&>(__rcvr));
267267
} else if constexpr (__with_member<_TfxSender, _Receiver>) { // NOLINT(bugprone-branch-clone)
268268
auto&& __tfx_sndr = transform_sender(static_cast<_Sender&&>(__sndr), __env);
269269
return static_cast<_TfxSender&&>(__tfx_sndr).connect(static_cast<_Receiver&&>(__rcvr));

0 commit comments

Comments
 (0)