**Section:** 26.7.26.1 [range.adjacent.overview], 26.7.27.1 [range.adjacent.transform.overview] **Status:** NAD
**Submitter:** Hewill Kang **Opened:** 2022-07-13 **Last modified:** 2022-11-30 17:59:24 UTC

**Priority: **Not Prioritized

**View all issues with** NAD status.

**Discussion:**

`views::adjacent` is very similar to `views::slide`, except that the window size
`N` is given at compile time.

Since the case where `N` is `0` does not make sense for `slide_view`,
LWG 3711 and LWG 3712 added preconditions to the constructor and
removed the default constructor, respectively.

But for `views::adjacent`, we can still specify `N` to be `0`. According to
the description of 26.7.26.1 [range.adjacent.overview],
it will return `views::empty<tuple<>>` as in the case of `views::zip`
applied to an empty pack. And for `views::adjacent_transform<0>(E, F)`, it will return
`views::zip_transform(F)` and eventually return `empty_view` for some type.

This doesn't seem reasonable to me. The reason why `views::zip` can return
`views::empty<tuple<>>` is that the parameter pack can indeed be empty, so
this still makes some sense. However, there is no meaningful sense for the word "adjacent" when
`N` is `0`.

I don't see any observable value in allowing `views::adjacent<0>`, we should disable
it for consistency with `views::slide`.

*[2022-08-23; Reflector poll: NAD]*

`views::zip()`

is exactly as meaningful as
`views::adjacent<0>(E)`

- it's just the edge case.

*[2022-11-30 LWG telecon. Status changed: Tentatively NAD → NAD.]*

**Proposed resolution:**

This wording is relative to N4910.

Modify 26.7.26.1 [range.adjacent.overview] as indicated:

-2- The name

`views::adjacent<N>`denotes a range adaptor object (26.7.2 [range.adaptor.object]). Given a subexpression`E`and a constant expression`N`, the expression`views::adjacent<N>(E)`is expression-equivalent to:(2.1) —

I`((void)E, auto(views::empty<tuple<>>))`~~i~~f`N`is equal to`0`,`views::adjacent<N>(E)`is ill-formed.(2.2) — O

~~o~~therwise,`adjacent_view<views::all_t<decltype((E))>, N>(E)`.

Modify 26.7.27.1 [range.adjacent.transform.overview] as indicated:

-2- The name

`views::adjacent_transform<N>`denotes a range adaptor object (26.7.2 [range.adaptor.object]). Given subexpressions`E`and`F`and a constant expression`N`:(2.1) — If

`N`is equal to`0`,`views::adjacent_transform<N>(E, F)`is ill-formed~~expression-equivalent to~~.`((void)E, views::zip_transform(F))`, except that the evaluations of`E`and`F`are indeterminately sequenced(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)`.