Title
generator::promise_type::yield_value(ranges::elements_of<R, Alloc>)'s nested generator may be ill-formed
Status
ready
Section
[coro.generator.promise]
Submitter
Hewill Kang

Created on 2024-07-11.00:00:00 last changed 2 months ago

Messages

Date: 2024-08-02.21:14:44

Proposed resolution:

This wording is relative to N4986.

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

    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);
    

    -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>void, 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: 2024-08-15.00:00:00

[ 2024-08-02; Reflector poll ]

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

Date: 2024-07-11.00:00:00

The nested coroutine is specified to return generator<yielded, ranges::range_value_t<R>, Alloc> which can be problematic as the value type of R is really irrelevant to yielded, unnecessarily violating the generator's Mandates (demo):

#include <generator>
#include <vector>

std::generator<std::span<int>> f() {
  std::vector<int> v;
  co_yield v; // ok
}

std::generator<std::span<int>> g() {
  std::vector<std::vector<int>> v;
  co_yield std::ranges::elements_of(v); // hard error
}

This proposed resolution is to change the second template parameter from range_value_t<R> to void since that type doesn't matter to us.

History
Date User Action Args
2024-08-02 21:14:44adminsetmessages: + msg14279
2024-08-02 21:14:44adminsetstatus: new -> ready
2024-07-21 08:52:21adminsetmessages: + msg14254
2024-07-11 00:00:00admincreate