Title
generator::promise_type::yield_value(ranges::elements_of<Rng, Alloc>) should not be noexcept
Status
wp
Section
[coro.generator.promise]
Submitter
Tim Song

Created on 2023-02-25.00:00:00 last changed 10 months ago

Messages

Date: 2023-06-19.14:50:03

Proposed resolution:

This wording is relative to N4928.

  1. Modify [coro.generator.promise] as indicated:

    namespace std {
      template<class Ref, class V, class Allocator>
      class generator<Ref, V, Allocator>::promise_type {
      public:
        […]
        auto yield_value(const remove_reference_t<yielded>& lval)
          requires is_rvalue_reference_v<yielded> &&
            constructible_from<remove_cvref_t<yielded>, const remove_reference_t<yielded>&>;
        
        template<class R2, class V2, class Alloc2, class Unused>
          requires same_as<typename generator<R2, V2, Alloc2>::yielded, yielded>
            auto yield_value(ranges::elements_of<generator<R2, V2, Alloc2>&&, Unused> g) noexcept;
        
        template<ranges::input_range R, class Alloc>
          requires convertible_to<ranges::range_reference_t<R>, yielded>
            auto yield_value(ranges::elements_of<R, Alloc> r) noexcept;
        […]
       };
    }
    
    […]
    template<ranges::input_range R, class Alloc>
      requires convertible_to<ranges::range_reference_t<R>, yielded>
      auto yield_value(ranges::elements_of<R, Alloc> r) noexcept;
    

    -13- Effects: Equivalent to:

    auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t<R> i, ranges::sentinel_t<R> s)
      -> generator<yielded, ranges::range_value_t<R>, Alloc> {
        for (; i != s; ++i) {
          co_yield static_cast<yielded>(*i);
        }
      };
    return yield_value(ranges::elements_of(nested(
      allocator_arg, r.allocator, ranges::begin(r.range), ranges::end(r.range))));
    
    […]
Date: 2023-06-17.00:00:00

[ 2023-06-17 Approved at June 2023 meeting in Varna. Status changed: Voting → WP. ]

Date: 2023-03-15.00:00:00

[ 2023-03-22; Reflector poll ]

Set status to Tentatively Ready after six votes in favour during reflector poll.

Date: 2023-02-25.00:00:00

The overload of yield_value for yielding elements of arbitrary ranges does so by creating a nested generator, but to do so it needs to:

  • call ranges::begin/ranges::end on the range

  • allocate a new coroutine frame (unless the allocation is elided by the compiler, which isn't guaranteed)

  • copy/move the iterator and sentinel into the coroutine frame

All of these are allowed to throw, so this overload should not be noexcept.

History
Date User Action Args
2023-06-19 14:50:03adminsetmessages: + msg13647
2023-06-19 14:50:03adminsetstatus: voting -> wp
2023-06-12 08:52:25adminsetstatus: ready -> voting
2023-03-22 22:32:48adminsetmessages: + msg13469
2023-03-22 22:32:48adminsetstatus: new -> ready
2023-02-25 15:31:58adminsetmessages: + msg13435
2023-02-25 00:00:00admincreate