Many of the types in
[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(const I i) { i.operator->(); });
template<class T, class U>
concept different-from =
!same_as<remove_cvref_t<T>, remove_cvref_t<U>>;
template<class R>
concept range-with-movable-references =
input_range<R> && move_constructible<range_reference_t<R>> &&
move_constructible<range_rvalue_reference_t<R>>;