3291. iota_view::iterator has the wrong iterator_category

Section: 25.6.4.3 [range.iota.iterator] Status: C++20 Submitter: Eric Niebler Opened: 2019-09-13 Last modified: 2021-02-25

Priority: 0

View other active issues in [range.iota.iterator].

View all other issues in [range.iota.iterator].

View all issues with C++20 status.

Discussion:

In the old way of looking at the world, forward iterators need to return real references. Since dereferencing iota_view's iterators returns by value, it cannot be a C++17 forward iterator. (It can, however, be a C++20 forward_iterator.) However, iota_view's iterator has an iterator_category that (sometimes) falsely claims that it is forward or better (depending on the properties of the weakly_incrementable type it wraps).

[2019-10-19 Issue Prioritization]

Status to Tentatively Ready and priority to 0 after eight positive votes on the reflector.

Proposed resolution:

This wording is relative to N4830.

  1. Modify 25.6.4.3 [range.iota.iterator] as indicated:

    namespace std::ranges {
      template<class W, class Bound>
      struct iota_view<W, Bound>::iterator {
      private:
        […]
      public:
        using iterator_conceptategory = see below;
        using iterator_category = input_iterator_tag;
        using value_type = W;
        using difference_type = IOTA-DIFF-T(W);
        […]
      };
      […]
    }
    

    -1- iterator::iterator_conceptategory is defined as follows:

    1. (1.1) — If W models advanceable, then iterator_conceptategory is random_access_iterator_tag.

    2. (1.2) — Otherwise, if W models decrementable, then iterator_conceptategory is bidirectional_iterator_tag.

    3. (1.3) — Otherwise, if W models incrementable, then iterator_conceptategory is forward_iterator_tag.

    4. (1.4) — Otherwise, iterator_conceptategory is input_iterator_tag.