diff --git a/include/exec/sequence/iterate.hpp b/include/exec/sequence/iterate.hpp index a85f37c94..6ab2d2908 100644 --- a/include/exec/sequence/iterate.hpp +++ b/include/exec/sequence/iterate.hpp @@ -178,7 +178,12 @@ namespace experimental::execution struct __subscribe_fn { template - constexpr auto operator()(__ignore, _Range&& __range) noexcept + constexpr auto operator()(__ignore, _Range&& __range) + noexcept(noexcept(std::ranges::begin(static_cast<_Range&&>(__range))) + && noexcept(std::ranges::end(static_cast<_Range&&>(__range))) + && __nothrow_move_constructible, + std::ranges::sentinel_t<_Range>, + _Receiver>) { return __operation{std::ranges::begin(static_cast<_Range&&>(__range)), std::ranges::end(static_cast<_Range&&>(__range)), diff --git a/test/exec/sequence/test_iterate.cpp b/test/exec/sequence/test_iterate.cpp index 408630a9a..cae2088fe 100644 --- a/test/exec/sequence/test_iterate.cpp +++ b/test/exec/sequence/test_iterate.cpp @@ -25,6 +25,26 @@ namespace { + struct begin_error + {}; + + struct begin_throws_range + { + using iterator = std::array::iterator; + + iterator begin() + { + throw begin_error{}; + } + + iterator end() noexcept + { + return values.end(); + } + + std::array values{0}; + }; + template struct sum_item_rcvr { @@ -140,4 +160,13 @@ namespace CHECK(sum == (42 + 43 + 44 + 1)); } + TEST_CASE("iterate - subscribe propagates begin exceptions", "[sequence_senders][iterate]") + { + auto iterate = exec::iterate(begin_throws_range{}); + int sum = 0; + + STATIC_REQUIRE_FALSE(noexcept(exec::subscribe(iterate, sum_receiver<>{.sum_ = sum}))); + CHECK_THROWS_AS(exec::subscribe(iterate, sum_receiver<>{.sum_ = sum}), begin_error); + } + } // namespace