3398. tuple_element_t is also wrong for const subrange

Section: 25.2 [ranges.syn] Status: C++20 Submitter: Casey Carter Opened: 2019-02-13 Last modified: 2021-02-25

Priority: 0

View other active issues in [ranges.syn].

View all other issues in [ranges.syn].

View all issues with C++20 status.

Discussion:

As currently specified, it uses the cv-qualified partial specialization, which incorrectly adds cv-qualification to the element type.

Previous resolution [SUPERSEDED]:

This wording is relative to N4849.

  1. Modify 25.2 [ranges.syn], header <ranges> synopsis, as indicated:

    […]
    namespace std {
      namespace views = ranges::views;
    
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_size<ranges::subrange<I, S, K>>
        : integral_constant<size_t, 2> {};
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<0, ranges::subrange<I, S, K>> {
        using type = I;
      };
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<1, ranges::subrange<I, S, K>> {
        using type = S;
      };
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<0, const ranges::subrange<I, S, K>> {
        using type = I;
      };
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<1, const ranges::subrange<I, S, K>> {
        using type = S;
      };
    }
    
  2. Add the following wording to Annex D:

    D.? Deprecated subrange tuple interface [depr.ranges.syn]

    1 The header <ranges> (25.2 [ranges.syn]) has the following additions:

    namespace std {
      template<size_t X, class I, class S, ranges::subrange_kind K>
      struct tuple_element<X, volatile ranges::subrange<I, S, K>> {};
      template<size_t X, class I, class S, ranges::subrange_kind K>
      struct tuple_element<X, const volatile ranges::subrange<I, S, K>> {};
    }
    

[2020-02-14, Prague]

LWG decided to remove the volatile support, we shouldn't give the impression to support an idiom that wouldn't work.

Proposed resolution:

This wording is relative to N4849.

  1. Modify 25.2 [ranges.syn], header <ranges> synopsis, as indicated:

    […]
    namespace std {
      namespace views = ranges::views;
    
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_size<ranges::subrange<I, S, K>>
        : integral_constant<size_t, 2> {};
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<0, ranges::subrange<I, S, K>> {
        using type = I;
      };
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<1, ranges::subrange<I, S, K>> {
        using type = S;
      };
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<0, const ranges::subrange<I, S, K>> {
        using type = I;
      };
      template<class I, class S, ranges::subrange_kind K>
      struct tuple_element<1, const ranges::subrange<I, S, K>> {
        using type = S;
      };
    }