3762. generator::iterator::operator== should pass by reference

Section: 25.8.6 [coro.generator.iterator] Status: C++23 Submitter: Hewill Kang Opened: 2022-08-27 Last modified: 2023-11-22

Priority: Not Prioritized

View other active issues in [coro.generator.iterator].

View all other issues in [coro.generator.iterator].

View all issues with C++23 status.

Discussion:

Currently, generator::iterator::operator== passes iterator by value. Given that iterator is a move-only type, this makes it impossible for generator to model range, since default_sentinel cannot be compared to the iterator of const lvalue and is not eligible to be its sentinel.

[2022-09-23; Reflector poll]

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

[2022-11-12 Approved at November 2022 meeting in Kona. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4917.

  1. Modify 25.8.6 [coro.generator.iterator] as indicated:

    namespace std {
      template<class Ref, class V, class Allocator>
      class generator<Ref, V, Allocator>::iterator {
      public:
        using value_type = value;
        using difference_type = ptrdiff_t;
    
        iterator(iterator&& other) noexcept;
        iterator& operator=(iterator&& other) noexcept;
        
        reference operator*() const noexcept(is_nothrow_copy_constructible_v<reference>);
        iterator& operator++();
        void operator++(int);
    
        friend bool operator==(const iterator& i, default_sentinel_t);
    
      private:
        coroutine_handle<promise_type> coroutine_; // exposition only
      };
    }
    

    […]

    friend bool operator==(const iterator& i, default_sentinel_t);
    

    -10- Effects: Equivalent to: return i.coroutine_.done();