[range.zip.view] (original) (raw)
25 Ranges library [ranges]
25.7 Range adaptors [range.adaptors]
25.7.25 Zip view [range.zip]
25.7.25.2 Class template zip_view [range.zip.view]
namespace std::ranges { template<class... Rs> concept zip-is-common = (sizeof...(Rs) == 1 && (common_range<Rs> && ...)) || (!(bidirectional_range<Rs> && ...) && (common_range<Rs> && ...)) || ((random_access_range<Rs> && ...) && (sized_range<Rs> && ...));template<input_range... Views> requires (view<Views> && ...) && (sizeof...(Views) > 0) class zip_view : public view_interface<zip_view<Views...>> { tuple<Views...> views_; template<bool> class iterator; template<bool> class sentinel; public: zip_view() = default;constexpr explicit zip_view(Views... views);constexpr auto begin() requires (!(simple-view<Views> && ...)) { return iterator<false>(tuple-transform(ranges::begin, views_));} constexpr auto begin() const requires (range<const Views> && ...) { return iterator<true>(tuple-transform(ranges::begin, views_));} constexpr auto end() requires (!(simple-view<Views> && ...)) { if constexpr (<Views...>) { return sentinel<false>(tuple-transform(ranges::end, views_));} else if constexpr ((random_access_range<Views> && ...)) { return begin() + iter_difference_t<_iterator_<false>>(size());} else { return iterator<false>(tuple-transform(ranges::end, views_));} } constexpr auto end() const requires (range<const Views> && ...) { if constexpr (
<const Views...>) { return sentinel<true>(tuple-transform(ranges::end, views_));} else if constexpr ((random_access_range<const Views> && ...)) { return begin() + iter_difference_t<_iterator_<true>>(size());} else { return iterator<true>(tuple-transform(ranges::end, views_));} } constexpr auto size() requires (sized_range<Views> && ...);constexpr auto size() const requires (sized_range<const Views> && ...);};template<class... Rs> zip_view(Rs&&...) -> zip_view<views::all_t<Rs>...>;}
Two zip_view objects have the same underlying sequence if and only if the corresponding elements of views_ are equal ([concepts.equality]) and have the same underlying sequence.
[Note 1:
In particular, comparison of iterators obtained from zip_view objects that do not have the same underlying sequence is not required to produce meaningful results ([iterator.concept.forward]).
— _end note_]
constexpr explicit zip_view(Views... views);
Effects: Initializes views_ with std::move(views)....
constexpr auto size() requires ([sized_range](range.sized#concept:sized%5Frange "25.4.3 Sized ranges [range.sized]")<Views> && ...);constexpr auto size() const requires ([sized_range](range.sized#concept:sized%5Frange "25.4.3 Sized ranges [range.sized]")<const Views> && ...);
Effects: Equivalent to:return apply([](auto... sizes) { using CT = make-unsigned-like-t<common_type_t<decltype(sizes)...>>;return ranges::min({CT(sizes)...});}, tuple-transform(ranges::size, views_));