[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 (_zip-is-common_<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 (_zip-is-common_<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_));