Files
2025-10-25 03:02:53 +03:00

306 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[range.zip.iterator]
# 25 Ranges library [[ranges]](./#ranges)
## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.zip.iterator)
### 25.7.25 Zip view [[range.zip]](range.zip#iterator)
#### 25.7.25.3 Class template zip_view::*iterator* [range.zip.iterator]
[🔗](#lib:zip_view::iterator)
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]")... Views>requires ([view](range.view#concept:view "25.4.5Views[range.view]")<Views> && ...) && (sizeof...(Views) > 0)template<bool Const>class zip_view<Views...>::*iterator* { tuple<iterator_t<*maybe-const*<Const, Views>>...> *current_*; // *exposition only*constexpr explicit *iterator*(tuple<iterator_t<*maybe-const*<Const, Views>>...>); // *exposition only*public:using iterator_category = input_iterator_tag; // not always presentusing iterator_concept = *see below*; using value_type = tuple<range_value_t<*maybe-const*<Const, Views>>...>; using difference_type = common_type_t<range_difference_t<*maybe-const*<Const, Views>>...>; *iterator*() = default; constexpr *iterator*(*iterator*<!Const> i)requires Const && ([convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<iterator_t<Views>, iterator_t<const Views>> && ...); constexpr auto operator*() const; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int) requires [*all-forward*](range.adaptor.helpers#concept:all-forward "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; constexpr *iterator*& operator--() requires [*all-bidirectional*](range.adaptor.helpers#concept:all-bidirectional "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; constexpr *iterator* operator--(int) requires [*all-bidirectional*](range.adaptor.helpers#concept:all-bidirectional "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; constexpr *iterator*& operator+=(difference_type x)requires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; constexpr *iterator*& operator-=(difference_type x)requires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; constexpr auto operator[](difference_type n) constrequires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires ([equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<iterator_t<*maybe-const*<Const, Views>>> && ...); friend constexpr auto operator<=>(const *iterator*& x, const *iterator*& y)requires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; friend constexpr *iterator* operator+(const *iterator*& i, difference_type n)requires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; friend constexpr *iterator* operator+(difference_type n, const *iterator*& i)requires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; friend constexpr *iterator* operator-(const *iterator*& i, difference_type n)requires [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>; friend constexpr difference_type operator-(const *iterator*& x, const *iterator*& y)requires ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<iterator_t<*maybe-const*<Const, Views>>,
iterator_t<*maybe-const*<Const, Views>>> && ...); friend constexpr auto iter_move(const *iterator*& i) noexcept(*see below*); friend constexpr void iter_swap(const *iterator*& l, const *iterator*& r) noexcept(*see below*)requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<iterator_t<*maybe-const*<Const, Views>>> && ...); };}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11540)
*iterator*::iterator_concept is defined as follows:
- [(1.1)](#1.1)
If [*all-random-access*](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...> is modeled,
then iterator_concept denotes random_access_iterator_tag[.](#1.1.sentence-1)
- [(1.2)](#1.2)
Otherwise,
if [*all-bidirectional*](range.adaptor.helpers#concept:all-bidirectional "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...> is modeled,
then iterator_concept denotes bidirectional_iterator_tag[.](#1.2.sentence-1)
- [(1.3)](#1.3)
Otherwise,
if [*all-forward*](range.adaptor.helpers#concept:all-forward "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...> is modeled,
then iterator_concept denotes forward_iterator_tag[.](#1.3.sentence-1)
- [(1.4)](#1.4)
Otherwise, iterator_concept denotes input_iterator_tag[.](#1.4.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11558)
*iterator*::iterator_category is present
if and only if [*all-forward*](range.adaptor.helpers#concept:all-forward "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...> is modeled[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11562)
If the invocation of any non-const member function of *iterator* exits via an exception,
the iterator acquires a singular value[.](#3.sentence-1)
[🔗](#lib:zip_view::iterator,constructor)
`constexpr explicit iterator(tuple<iterator_t<maybe-const<Const, Views>>...> current);
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11573)
*Effects*: Initializes *current_* with std::move(current)[.](#4.sentence-1)
[🔗](#lib:zip_view::iterator,constructor_)
`constexpr iterator(iterator<!Const> i)
requires Const && ([convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<iterator_t<Views>, iterator_t<const Views>> && ...);
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11585)
*Effects*: Initializes *current_* with std::move(i.*current_*)[.](#5.sentence-1)
[🔗](#lib:operator*,izip_view::iterator)
`constexpr auto operator*() const;
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11596)
*Effects*: Equivalent to:return *tuple-transform*([](auto& i) -> decltype(auto) { return *i; }, *current_*);
[🔗](#lib:operator++,izip_view::iterator)
`constexpr iterator& operator++();
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11610)
*Effects*: Equivalent to:*tuple-for-each*([](auto& i) { ++i; }, *current_*);return *this;
[🔗](#lib:operator++,izip_view::iterator_)
`constexpr void operator++(int);
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11625)
*Effects*: Equivalent to ++*this[.](#8.sentence-1)
[🔗](#lib:operator++,izip_view::iterator__)
`constexpr iterator operator++(int) requires [all-forward](range.adaptor.helpers#concept:all-forward "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11636)
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
[🔗](#lib:operator--,izip_view::iterator)
`constexpr iterator& operator--() requires [all-bidirectional](range.adaptor.helpers#concept:all-bidirectional "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11652)
*Effects*: Equivalent to:*tuple-for-each*([](auto& i) { --i; }, *current_*);return *this;
[🔗](#lib:operator--,izip_view::iterator_)
`constexpr iterator operator--(int) requires [all-bidirectional](range.adaptor.helpers#concept:all-bidirectional "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11667)
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
[🔗](#lib:operator+=,izip_view::iterator)
`constexpr iterator& operator+=(difference_type x)
requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11684)
*Effects*: Equivalent to:*tuple-for-each*([&]<class I>(I& i) { i += iter_difference_t<I>(x); }, *current_*);return *this;
[🔗](#lib:operator-=,izip_view::iterator)
`constexpr iterator& operator-=(difference_type x)
requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11700)
*Effects*: Equivalent to:*tuple-for-each*([&]<class I>(I& i) { i -= iter_difference_t<I>(x); }, *current_*);return *this;
[🔗](#lib:operator%5b%5d,izip_view::iterator)
`constexpr auto operator[](difference_type n) const
requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11716)
*Effects*: Equivalent to:return *tuple-transform*([&]<class I>(I& i) -> decltype(auto) {return i[iter_difference_t<I>(n)];}, *current_*);
[🔗](#lib:operator==,izip_view::iterator)
`friend constexpr bool operator==(const iterator& x, const iterator& y)
requires ([equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<iterator_t<maybe-const<Const, Views>>> && ...);
`
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11733)
*Returns*:
- [(15.1)](#15.1)
x.*current_* == y.*current_* if [*all-bidirectional*](range.adaptor.helpers#concept:all-bidirectional "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...> is true[.](#15.1.sentence-1)
- [(15.2)](#15.2)
Otherwise, true if there exists an integer 0≤i<sizeof...(Views) such that bool(std::get<i>(x.*current_*) == std::get<i>(y.*current_*)) is true[.](#15.2.sentence-1)
[*Note [1](#note-1)*:
This allows zip_view to model [common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]") when all constituent views model [common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]")[.](#15.2.sentence-2)
— *end note*]
- [(15.3)](#15.3)
Otherwise, false[.](#15.3.sentence-1)
[🔗](#lib:operator%3c=%3e,izip_view::iterator)
`friend constexpr auto operator<=>(const iterator& x, const iterator& y)
requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11760)
*Returns*: x.*current_* <=> y.*current_*[.](#16.sentence-1)
[🔗](#lib:operator+,izip_view::iterator)
`friend constexpr iterator operator+(const iterator& i, difference_type n)
requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
friend constexpr iterator operator+(difference_type n, const iterator& i)
requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11774)
*Effects*: Equivalent to:auto r = i;
r += n;return r;
[🔗](#lib:operator-,izip_view::iterator)
`friend constexpr iterator operator-(const iterator& i, difference_type n)
requires [all-random-access](range.adaptor.helpers#concept:all-random-access "25.7.5Range adaptor helpers[range.adaptor.helpers]")<Const, Views...>;
`
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11791)
*Effects*: Equivalent to:auto r = i;
r -= n;return r;
[🔗](#lib:operator-,izip_view::iterator_)
`friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires ([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<iterator_t<maybe-const<Const, Views>>,
iterator_t<maybe-const<Const, Views>>> && ...);
`
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11809)
Let *DIST*(i) be difference_type(std::get<i>(x.*current_*) - std::get<i>(y.*current_*))[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11812)
*Returns*: The value with the smallest absolute value among *DIST*(n) for all integers 0≤n<sizeof...(Views)[.](#20.sentence-1)
[🔗](#lib:iter_move,izip_view::iterator)
`friend constexpr auto iter_move(const iterator& i) noexcept(see below);
`
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11824)
*Effects*: Equivalent to:return *tuple-transform*(ranges::iter_move, i.*current_*);
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11831)
*Remarks*: The exception specification is equivalent to:(noexcept(ranges::iter_move(declval<const iterator_t<*maybe-const*<Const,
Views>>&>())) && ...) &&(is_nothrow_move_constructible_v<range_rvalue_reference_t<*maybe-const*<Const,
Views>>> && ...)
[🔗](#lib:iter_swap,izip_view::iterator)
`friend constexpr void iter_swap(const iterator& l, const iterator& r) noexcept(see below)
requires ([indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<iterator_t<maybe-const<Const, Views>>> && ...);
`
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11849)
*Effects*: For every integer 0≤i<sizeof...(Views),
performs:ranges::iter_swap(std::get<i>(l.*current_*), std::get<i>(r.*current_*))
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L11857)
*Remarks*: The exception specification is equivalent to
the logical and of the following expressions:noexcept(ranges::iter_swap(std::get<i>(l.*current_*), std::get<i>(r.*current_*))) for every integer 0≤i<sizeof...(Views)[.](#24.sentence-1)