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