[range.zip.view]

# 25 Ranges library [[ranges]](./#ranges)

## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.zip.view)

### 25.7.25 Zip view [[range.zip]](range.zip#view)

#### 25.7.25.2 Class template zip_view [range.zip.view]

[ð](#lib:zip_view)

namespace std::ranges {template<class... Rs>concept [*zip-is-common*](#concept:zip-is-common "25.7.25.2 Class template zip_­view [range.zip.view]") = // *exposition only*(sizeof...(Rs) == 1 && ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...)) ||(!([bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...) && ([common_range](range.refinements#concept:common_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...)) ||(([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Rs> && ...) && ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Rs> && ...)); template<[input_range](range.refinements#concept:input_range "25.4.6 Other range refinements [range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5 Views [range.view]")<Views> && ...) && (sizeof...(Views) > 0)class zip_view : public view_interface<zip_view<Views...>> { tuple<Views...> *views_*; // *exposition only*// [[range.zip.iterator]](range.zip.iterator "25.7.25.3 Class template zip_­view​::​iterator"), class template zip_view​::​*iterator*template<bool> class *iterator*; // *exposition only*// [[range.zip.sentinel]](range.zip.sentinel "25.7.25.4 Class template zip_­view​::​sentinel"), class template zip_view​::​*sentinel*template<bool> class *sentinel*; // *exposition only*public: zip_view() = default; constexpr explicit zip_view(Views... views); constexpr auto begin() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...)) {return *iterator*<false>(*tuple-transform*(ranges::begin, *views_*)); }constexpr auto begin() const requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) {return *iterator*<true>(*tuple-transform*(ranges::begin, *views_*)); }constexpr auto end() requires (!([*simple-view*](range.utility.helpers#concept:simple-view "25.5.2 Helper concepts [range.utility.helpers]")<Views> && ...)) {if constexpr (![*zip-is-common*](#concept:zip-is-common "25.7.25.2 Class template zip_­view [range.zip.view]")<Views...>) {return *sentinel*<false>(*tuple-transform*(ranges::end, *views_*)); } else if constexpr (([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<Views> && ...)) {return begin() + iter_difference_t<*iterator*<false>>(size()); } else {return *iterator*<false>(*tuple-transform*(ranges::end, *views_*)); }}constexpr auto end() const requires ([range](range.range#concept:range "25.4.2 Ranges [range.range]")<const Views> && ...) {if constexpr (![*zip-is-common*](#concept:zip-is-common "25.7.25.2 Class template zip_­view [range.zip.view]")<const Views...>) {return *sentinel*<true>(*tuple-transform*(ranges::end, *views_*)); } else if constexpr (([random_access_range](range.refinements#concept:random_access_range "25.4.6 Other range refinements [range.refinements]")<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](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Views> && ...); constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const Views> && ...); }; template<class... Rs> zip_view(Rs&&...) -> zip_view<views::all_t<Rs>...>;}

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11439)

Two zip_view objects have the same underlying sequence if and only if
the corresponding elements of *views_* are equal ([[concepts.equality]](concepts.equality "18.2 Equality preservation"))
and have the same underlying sequence[.](#1.sentence-1)

[*Note [1](#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]](iterator.concept.forward "24.3.4.11 Concept forward_­iterator"))[.](#1.sentence-2)

â *end note*]

[ð](#lib:zip_view,constructor)

`constexpr explicit zip_view(Views... views);
`

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11455)

*Effects*: Initializes *views_* with std​::​move(views)...[.](#2.sentence-1)

[ð](#lib:size,zip_view)

`constexpr auto size() requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<Views> && ...);
constexpr auto size() const requires ([sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")<const Views> && ...);
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11467)

*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_*));
