4098. views::adjacent<0> should reject non-forward ranges

Section: 25.7.27.1 [range.adjacent.overview], 25.7.28.1 [range.adjacent.transform.overview] Status: WP Submitter: Hewill Kang Opened: 2024-05-10 Last modified: 2024-07-08

Priority: Not Prioritized

View all other issues in [range.adjacent.overview].

View all issues with WP status.

Discussion:

Following-up LWG 4082 and LWG 4083, the current wording makes views::adjacent<0>(r) and views::adjacent_transform<0>(r, [] { return 0; }) well-formed even when r is just an input range or an output range, which seems to be an oversight.

[2024-06-24; Reflector poll]

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

[St. Louis 2024-06-29; Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4981.

  1. Modify 25.7.27.1 [range.adjacent.overview] as indicated:

    -2- The name views::adjacent<N> denotes a range adaptor object (25.7.2 [range.adaptor.object]). Given a subexpression E and a constant expression N, the expression views::adjacent<N>(E) is expression-equivalent to

    1. (2.1) — ((void)E, auto(views::empty<tuple<>>)) if N is equal to 0 and decltype((E)) models forward_range,

    2. (2.2) — otherwise, adjacent_view<views::all_t<decltype((E))>, N>(E).

  2. Modify 25.7.28.1 [range.adjacent.transform.overview] as indicated:

    -2- The name views::adjacent_transform<N> denotes a range adaptor object (25.7.2 [range.adaptor.object]). Given subexpressions E and F and a constant expression N:

    1. (2.1) — If N is equal to 0 and decltype((E)) models forward_range, views::adjacent_transform<N>(E, F) is expression-equivalent to ((void)E, views::zip_transform(F)), except that the evaluations of E and F are indeterminately sequenced.

    2. (2.2) — Otherwise, the expression views::adjacent_transform<N>(E, F) is expression-equivalent to adjacent_transform_view<views::all_t<decltype((E))>, decay_t<decltype((F))>, N>(E, F).