namespace std::ranges {
template<move_constructible F, input_range... Views>
requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
regular_invocable<F&, range_reference_t<Views>...> &&
can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
class zip_transform_view : public view_interface<zip_transform_view<F, Views...>> {
movable-box<F> fun_;
zip_view<Views...> zip_;
using InnerView = zip_view<Views...>;
template<bool Const>
using ziperator = iterator_t<maybe-const<Const, InnerView>>;
template<bool Const>
using zentinel = sentinel_t<maybe-const<Const, InnerView>>;
template<bool> class iterator;
template<bool> class sentinel;
public:
zip_transform_view() = default;
constexpr explicit zip_transform_view(F fun, Views... views);
constexpr auto begin() { return iterator<false>(*this, zip_.begin()); }
constexpr auto begin() const
requires range<const InnerView> &&
regular_invocable<const F&, range_reference_t<const Views>...> {
return iterator<true>(*this, zip_.begin());
}
constexpr auto end() {
if constexpr (common_range<InnerView>) {
return iterator<false>(*this, zip_.end());
} else {
return sentinel<false>(zip_.end());
}
}
constexpr auto end() const
requires range<const InnerView> &&
regular_invocable<const F&, range_reference_t<const Views>...> {
if constexpr (common_range<const InnerView>) {
return iterator<true>(*this, zip_.end());
} else {
return sentinel<true>(zip_.end());
}
}
constexpr auto size() requires sized_range<InnerView> {
return zip_.size();
}
constexpr auto size() const requires sized_range<const InnerView> {
return zip_.size();
}
};
template<class F, class... Rs>
zip_transform_view(F, Rs&&...) -> zip_transform_view<F, views::all_t<Rs>...>;
}
constexpr explicit zip_transform_view(F fun, Views... views);
Effects: Initializes
fun_ with
std::move(fun) and
zip_ with
std::move(views)....