Many of the types in subclause
[range.utility] are specified in terms of
the following exposition-only concepts:
template<class R>
concept simple-view =
view<R> && range<const R> &&
same_as<iterator_t<R>, iterator_t<const R>> &&
same_as<sentinel_t<R>, sentinel_t<const R>>;
template<class I>
concept has-arrow =
input_iterator<I> && (is_pointer_v<I> || requires(I i) { i.operator->(); });
template<class T, class U>
concept not-same-as =
!same_as<remove_cvref_t<T>, remove_cvref_t<U>>;