namespace std::ranges {
template<forward_range V, move_constructible F, size_t N>
requires view<V> && (N > 0) && is_object_v<F> &&
regular_invocable<F&, REPEAT(range_reference_t<V>, N)...> &&
can-reference<invoke_result_t<F&, REPEAT(range_reference_t<V>, N)...>>
class adjacent_transform_view : public view_interface<adjacent_transform_view<V, F, N>> {
movable-box<F> fun_;
adjacent_view<V, N> inner_;
using InnerView = adjacent_view<V, N>;
template<bool Const>
using inner-iterator = iterator_t<maybe-const<Const, InnerView>>;
template<bool Const>
using inner-sentinel = sentinel_t<maybe-const<Const, InnerView>>;
template<bool> class iterator;
template<bool> class sentinel;
public:
adjacent_transform_view() = default;
constexpr explicit adjacent_transform_view(V base, F fun);
constexpr V base() const & requires copy_constructible<InnerView> { return inner_.base(); }
constexpr V base() && { return std::move(inner_).base(); }
constexpr auto begin() {
return iterator<false>(*this, inner_.begin());
}
constexpr auto begin() const
requires range<const InnerView> &&
regular_invocable<const F&, REPEAT(range_reference_t<const V>, N)...> {
return iterator<true>(*this, inner_.begin());
}
constexpr auto end() {
if constexpr (common_range<InnerView>) {
return iterator<false>(*this, inner_.end());
} else {
return sentinel<false>(inner_.end());
}
}
constexpr auto end() const
requires range<const InnerView> &&
regular_invocable<const F&, REPEAT(range_reference_t<const V>, N)...> {
if constexpr (common_range<const InnerView>) {
return iterator<true>(*this, inner_.end());
} else {
return sentinel<true>(inner_.end());
}
}
constexpr auto size() requires sized_range<InnerView> {
return inner_.size();
}
constexpr auto size() const requires sized_range<const InnerView> {
return inner_.size();
}
};
}
constexpr explicit adjacent_transform_view(V base, F fun);
Effects: Initializes
fun_ with
std::move(fun) and
inner_ with
std::move(base).