From 62c7d224073511050046ff1d312424203f997909 Mon Sep 17 00:00:00 2001 From: Robert Leahy Date: Sat, 21 Feb 2026 13:28:31 -0500 Subject: [PATCH] exec::repeat_until et al.: Dependent Child Sender Support The TODO eliminated by this commit not only meant that exec:: repeat_until et al. previously didn't the usual constant evaluation techniques to report errors, it also meant that a hard compile error (rather than a return type indicating that the sender is dependent) resulted if: - The child sender was dependent, and - An attempt was made to determine the completion signatures of the parent without an environment Updated so exec::repeat_until et al. now properly report that they are dependent if their child is dependent. --- include/exec/repeat_until.hpp | 19 +++++++++++++++++-- test/exec/test_repeat_until.cpp | 19 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/exec/repeat_until.hpp b/include/exec/repeat_until.hpp index 189f76108..e5f6d5d8d 100644 --- a/include/exec/repeat_until.hpp +++ b/include/exec/repeat_until.hpp @@ -255,13 +255,28 @@ namespace experimental::execution __delete_set_value_t>, __mbind_front_q<__values_t, _Child>::template __f>; + struct _FAILED_TO_FORM_COMPLETION_SIGNATURES + {}; + struct __repeat_until_impl : __sexpr_defaults { template static consteval auto __get_completion_signatures() { - // TODO: port this to use constant evaluation - return __completions_t<__child_of<_Sender>, _Env...>{}; + using __child_t = __child_of<_Sender>; + if constexpr (::STDEXEC::__minvocable_q<__completions_t, __child_t, _Env...>) + { + return __completions_t<__child_t, _Env...>{}; + } + else if constexpr (sizeof...(_Env) == 0) + { + return STDEXEC::__dependent_sender<_Sender>(); + } + else + { + return ::STDEXEC::__throw_compile_time_error<_FAILED_TO_FORM_COMPLETION_SIGNATURES, + ::STDEXEC::_WITH_PRETTY_SENDER_<_Sender>>(); + } }; static constexpr auto __connect = diff --git a/test/exec/test_repeat_until.cpp b/test/exec/test_repeat_until.cpp index 9401f6b94..95bfd52d0 100644 --- a/test/exec/test_repeat_until.cpp +++ b/test/exec/test_repeat_until.cpp @@ -28,9 +28,11 @@ #include #include +#include #include #include #include +#include #include namespace ex = STDEXEC; @@ -407,4 +409,21 @@ namespace { "Missing added set_error_t(std::exception_ptr)"); } } + + TEST_CASE("repeat_until works with a dependent sender", "[adaptors][repeat_until]") + { + std::size_t invoked = 0; + auto snd = exec::repeat_until(ex::read_env(ex::get_stop_token) + | ex::then( + [&](auto token) noexcept + { + ++invoked; + return std::is_same_v; + })); + static_assert(ex::dependent_sender); + auto op = ex::connect(std::move(snd), expect_void_receiver{}); + CHECK(!invoked); + ex::start(op); + CHECK(invoked == 1); + } } // namespace