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

537 lines
29 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.concat.iterator]
# 25 Ranges library [[ranges]](./#ranges)
## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.concat.iterator)
### 25.7.18 Concat view [[range.concat]](range.concat#iterator)
#### 25.7.18.3 Class concat_view::*iterator* [range.concat.iterator]
[🔗](#lib:iterator,concat_view)
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) &&[*concatable*](range.concat.view#concept:concatable "25.7.18.2Class template concat_­view[range.concat.view]")<Views...>template<bool Const>class concat_view<Views...>::*iterator* {public:using iterator_category = *see below*; // not always presentusing iterator_concept = *see below*; using value_type = *concat-value-t*<*maybe-const*<Const, Views>...>; using difference_type = common_type_t<range_difference_t<*maybe-const*<Const, Views>>...>; private:using *base-iter* = // *exposition only* variant<iterator_t<*maybe-const*<Const, Views>>...>; *maybe-const*<Const, concat_view>* *parent_* = nullptr; // *exposition only**base-iter* *it_*; // *exposition only*template<size_t N>constexpr void *satisfy*(); // *exposition only*template<size_t N>constexpr void *prev*(); // *exposition only*template<size_t N>constexpr void *advance-fwd*(difference_type offset, // *exposition only* difference_type steps); template<size_t N>constexpr void *advance-bwd*(difference_type offset, // *exposition only* difference_type steps); template<class... Args>constexpr explicit *iterator*(*maybe-const*<Const, concat_view>* parent, // *exposition only* Args&&... args)requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<*base-iter*, Args&&...>; public:*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 decltype(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 [*concat-is-bidirectional*](range.concat.view#concept:concat-is-bidirectional "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; constexpr *iterator* operator--(int)requires [*concat-is-bidirectional*](range.concat.view#concept:concat-is-bidirectional "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; constexpr *iterator*& operator+=(difference_type n)requires [*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; constexpr *iterator*& operator-=(difference_type n)requires [*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; constexpr decltype(auto) operator[](difference_type n) constrequires [*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<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 bool operator==(const *iterator*& it, default_sentinel_t); friend constexpr bool 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 bool 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 bool 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 bool 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 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...> &&([three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<iterator_t<*maybe-const*<Const, Views>>> && ...)); friend constexpr *iterator* operator+(const *iterator*& it, difference_type n)requires [*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; friend constexpr *iterator* operator+(difference_type n, const *iterator*& it)requires [*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; friend constexpr *iterator* operator-(const *iterator*& it, difference_type n)requires [*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; friend constexpr difference_type operator-(const *iterator*& x, const *iterator*& y)requires [*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>; friend constexpr difference_type operator-(const *iterator*& x, default_sentinel_t)requires *see below*; friend constexpr difference_type operator-(default_sentinel_t, const *iterator*& x)requires *see below*; friend constexpr decltype(auto) iter_move(const *iterator*& it) noexcept(*see below*); friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y) noexcept(*see below*)requires *see below*; };}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9035)
*iterator*::iterator_concept is defined as follows:
- [(1.1)](#1.1)
If[*concat-is-random-access*](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...> is modeled,
then iterator_concept denotes random_access_iterator_tag[.](#1.1.sentence-1)
- [(1.2)](#1.2)
Otherwise, if[*concat-is-bidirectional*](range.concat.view#concept:concat-is-bidirectional "25.7.18.2Class template concat_­view[range.concat.view]")<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#L9054)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_category is defined
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)
In that case,*iterator*::iterator_category is defined as follows:
- [(2.1)](#2.1)
Ifis_reference_v<*concat-reference-t*<*maybe-const*<Const, Views>...>> is false,
then iterator_category denotes input_iterator_tag[.](#2.1.sentence-1)
- [(2.2)](#2.2)
Otherwise,
let Cs denote the pack of typesiterator_traits<iterator_t<*maybe-const*<Const, Views>>>::iterator_category...[.](#2.2.sentence-1)
* [(2.2.1)](#2.2.1)
If([derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<Cs, random_access_iterator_tag> && ...) && *concat-is-random-access*<Const, Views...> is true,iterator_category denotes random_access_iterator_tag[.](#2.2.1.sentence-1)
* [(2.2.2)](#2.2.2)
Otherwise, if([derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<Cs, bidirectional_iterator_tag> && ...) && *concat-is-bidirectional*<Const, Views...> is true,iterator_category denotes bidirectional_iterator_tag[.](#2.2.2.sentence-1)
* [(2.2.3)](#2.2.3)
Otherwise, if([derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<Cs, forward_iterator_tag> && ...) is true,iterator_category denotes forward_iterator_tag[.](#2.2.3.sentence-1)
* [(2.2.4)](#2.2.4)
Otherwise, iterator_category denotes input_iterator_tag[.](#2.2.4.sentence-1)
[🔗](#lib:satisfy,concat_view::iterator)
`template<size_t N>
constexpr void satisfy();
`
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9100)
*Effects*: Equivalent to:if constexpr (N < (sizeof...(Views) - 1)) {if (std::get<N>(*it_*) == ranges::end(std::get<N>(*parent_*->*views_*))) {*it_*.template emplace<N + 1>(ranges::begin(std::get<N + 1>(*parent_*->*views_*))); *satisfy*<N + 1>(); }}
[🔗](#lib:prev,concat_view::iterator)
`template<size_t N>
constexpr void prev();
`
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9120)
*Effects*: Equivalent to:if constexpr (N == 0) {--std::get<0>(*it_*);} else {if (std::get<N>(*it_*) == ranges::begin(std::get<N>(*parent_*->*views_*))) {*it_*.template emplace<N - 1>(ranges::end(std::get<N - 1>(*parent_*->*views_*))); *prev*<N - 1>(); } else {--std::get<N>(*it_*); }}
[🔗](#lib:advance-fwd,concat_view::iterator)
`template<size_t N>
constexpr void advance-fwd(difference_type offset, difference_type steps);
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9144)
*Effects*: Equivalent to:using underlying_diff_type = iter_difference_t<variant_alternative_t<N, *base-iter*>>;if constexpr (N == sizeof...(Views) - 1) { std::get<N>(*it_*) += static_cast<underlying_diff_type>(steps);} else {auto n_size = ranges::distance(std::get<N>(*parent_*->*views_*)); if (offset + steps < n_size) { std::get<N>(*it_*) += static_cast<underlying_diff_type>(steps); } else {*it_*.template emplace<N + 1>(ranges::begin(std::get<N + 1>(*parent_*->*views_*))); *advance-fwd*<N + 1>(0, offset + steps - n_size); }}
[🔗](#lib:advance-bwd,concat_view::iterator)
`template<size_t N>
constexpr void advance-bwd(difference_type offset, difference_type steps);
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9170)
*Effects*: Equivalent to:using underlying_diff_type = iter_difference_t<variant_alternative_t<N, *base-iter*>>;if constexpr (N == 0) { std::get<N>(*it_*) -= static_cast<underlying_diff_type>(steps);} else {if (offset >= steps) { std::get<N>(*it_*) -= static_cast<underlying_diff_type>(steps); } else {auto prev_size = ranges::distance(std::get<N - 1>(*parent_*->*views_*)); *it_*.template emplace<N - 1>(ranges::end(std::get<N - 1>(*parent_*->*views_*))); *advance-bwd*<N - 1>(prev_size, steps - offset); }}
[🔗](#lib:concat_view::iterator,constructor)
`template<class... Args>
constexpr explicit iterator(maybe-const<Const, concat_view>* parent,
Args&&... args)
requires [constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<base-iter, Args&&...>;
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9198)
*Effects*: Initializes *parent_* with parent, and
initializes *it_* with std::forward<Args>(args)...[.](#7.sentence-1)
[🔗](#lib:concat_view::iterator,constructor_)
`constexpr iterator(iterator<!Const> it)
requires Const &&
([convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<iterator_t<Views>, iterator_t<const Views>> && ...);
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9212)
*Preconditions*: it.*it_*.valueless_by_exception() is false[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9216)
*Effects*: Initializes *parent_* with it.*parent_*, and
let i be it.*it_*.index(),
initializes *it_* with*base-iter*(in_place_index<i>, std::get<i>(std::move(it.*it_*)))[.](#9.sentence-1)
[🔗](#lib:operator*,concat_view::iterator)
`constexpr decltype(auto) operator*() const;
`
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9230)
*Preconditions*: *it_*.valueless_by_exception() is false[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9234)
*Effects*: Equivalent to:using reference = *concat-reference-t*<*maybe-const*<Const, Views>...>;return std::visit([](auto&& it) -> reference { return *it; }, *it_*);
[🔗](#lib:operator++,concat_view::iterator)
`constexpr iterator& operator++();
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9250)
*Preconditions*: *it_*.valueless_by_exception() is false[.](#12.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9254)
*Effects*: Let i be *it_*.index()[.](#13.sentence-1)
Equivalent to:++std::get<i>(*it_*);*satisfy*<i>();return *this;
[🔗](#lib:operator++,concat_view::iterator_)
`constexpr void operator++(int);
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9271)
*Effects*: Equivalent to:++*this;
[🔗](#lib:operator++,concat_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...>;
`
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9286)
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
[🔗](#lib:operator--,concat_view::iterator)
`constexpr iterator& operator--()
requires [concat-is-bidirectional](range.concat.view#concept:concat-is-bidirectional "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9303)
*Preconditions*: *it_*.valueless_by_exception() is false[.](#16.sentence-1)
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9307)
*Effects*: Let i be *it_*.index()[.](#17.sentence-1)
Equivalent to:*prev*<i>();return *this;
[🔗](#lib:operator--,concat_view::iterator_)
`constexpr iterator operator--(int)
requires [concat-is-bidirectional](range.concat.view#concept:concat-is-bidirectional "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9324)
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
[🔗](#lib:operator+=,concat_view::iterator)
`constexpr iterator& operator+=(difference_type n)
requires [concat-is-random-access](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9341)
*Preconditions*: *it_*.valueless_by_exception() is false[.](#19.sentence-1)
[20](#20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9345)
*Effects*: Let i be *it_*.index()[.](#20.sentence-1)
Equivalent to:if (n > 0) {*advance-fwd*<i>(std::get<i>(*it_*) - ranges::begin(std::get<i>(*parent_*->*views_*)), n);} else if (n < 0) {*advance-bwd*<i>(std::get<i>(*it_*) - ranges::begin(std::get<i>(*parent_*->*views_*)), -n);}return *this;
[🔗](#lib:operator-=,concat_view::iterator)
`constexpr iterator& operator-=(difference_type n)
requires [concat-is-random-access](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[21](#21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9366)
*Effects*: Equivalent to:*this += -n;return *this;
[🔗](#lib:operator%5b%5d,concat_view::iterator)
`constexpr decltype(auto) operator[](difference_type n) const
requires [concat-is-random-access](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[22](#22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9382)
*Effects*: Equivalent to:return *((*this) + n);
[🔗](#lib:operator==,concat_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>>> && ...);
`
[23](#23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9397)
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#23.sentence-1)
[24](#24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9402)
*Effects*: Equivalent to:return x.*it_* == y.*it_*;
[🔗](#lib:operator==,concat_view::iterator_)
`friend constexpr bool operator==(const iterator& it, default_sentinel_t);
`
[25](#25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9416)
*Preconditions*: it.*it_*.valueless_by_exception() is false[.](#25.sentence-1)
[26](#26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9420)
*Effects*: Equivalent to:constexpr auto last_idx = sizeof...(Views) - 1;return it.*it_*.index() == last_idx && std::get<last_idx>(it.*it_*) == ranges::end(std::get<last_idx>(it.*parent_*->*views_*));
[🔗](#lib:operator%3c,concat_view::iterator)
`friend constexpr bool 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 bool 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 bool 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 bool 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 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...> &&
([three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4Concept three_­way_­comparable[cmp.concept]")<iterator_t<maybe-const<Const, Views>>> && ...));
`
[27](#27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9446)
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#27.sentence-1)
[28](#28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9451)
Let op be the operator[.](#28.sentence-1)
[29](#29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9454)
*Effects*: Equivalent to:return x.*it_* op y.*it_*;
[🔗](#lib:operator+,concat_view::iterator)
`friend constexpr iterator operator+(const iterator& it, difference_type n)
requires [concat-is-random-access](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[30](#30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9469)
*Effects*: Equivalent to:auto temp = it;
temp += n;return temp;
[🔗](#lib:operator+,concat_view::iterator_)
`friend constexpr iterator operator+(difference_type n, const iterator& it)
requires [concat-is-random-access](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[31](#31)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9486)
*Effects*: Equivalent to:return it + n;
[🔗](#lib:operator-,concat_view::iterator)
`friend constexpr iterator operator-(const iterator& it, difference_type n)
requires [concat-is-random-access](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[32](#32)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9501)
*Effects*: Equivalent to:auto temp = it;
temp -= n;return temp;
[🔗](#lib:operator-,concat_view::iterator_)
`friend constexpr difference_type operator-(const iterator& x, const iterator& y)
requires [concat-is-random-access](range.concat.view#concept:concat-is-random-access "25.7.18.2Class template concat_­view[range.concat.view]")<Const, Views...>;
`
[33](#33)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9518)
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#33.sentence-1)
[34](#34)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9523)
*Effects*: Letix denote x.*it_*.index() andiy denote y.*it_*.index()[.](#34.sentence-1)
- [(34.1)](#34.1)
If ix > iy, letdy beranges::distance(std::get<iy>(y.*it_*), ranges::end(std::get<iy>(y.*parent_*->*views_*))),dx beranges::distance(ranges::begin(std::get<ix>(x.*parent_*->*views_*)), std::get<ix>(x.*it_*)). Let s denote the sum of the sizes of all the rangesstd::get<i>(x.*parent_*->*views_*) for every integer i in the range
[iy + 1, ix)
if there is any, and0 otherwise,
of type difference_type,
equivalent to:return dy + s + dx;
- [(34.2)](#34.2)
otherwise, if ix < iy is true,
equivalent to:return -(y - x);
- [(34.3)](#34.3)
otherwise, equivalent to:return std::get<ix>(x.*it_*) - std::get<iy>(y.*it_*);
[🔗](#lib:operator-,concat_view::iterator__)
`friend constexpr difference_type operator-(const iterator& x, default_sentinel_t)
requires see below;
`
[35](#35)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9571)
*Preconditions*: x.*it_*.valueless_by_exception() is false[.](#35.sentence-1)
[36](#36)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9575)
*Effects*: Letix denote x.*it_*.index(),dx beranges::distance(std::get<ix>(x.*it_*), ranges::end(std::get<ix>(x.*parent_*->*views_*)))[.](#36.sentence-1)
Let s denote the sum of the sizes of all the rangesstd::get<i>(x.*parent_*->*views_*) for every integer i in the range
[ix + 1, sizeof...(Views))
if there is any, and0 otherwise,
of type difference_type,
equivalent to:return -(dx + s);
[37](#37)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9594)
*Remarks*: Let Fs be the pack that consists of all elements of Views except the first element,
the expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]") is equivalent to:([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<sentinel_t<*maybe-const*<Const, Views>>,
iterator_t<*maybe-const*<Const, Views>>> && ...) &&([sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<*maybe-const*<Const, Fs>> && ...)
[🔗](#lib:operator-,concat_view::iterator___)
`friend constexpr difference_type operator-(default_sentinel_t, const iterator& x)
requires see below;
`
[38](#38)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9614)
*Effects*: Equivalent to:return -(x - default_sentinel);
[39](#39)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9621)
*Remarks*: Let Fs be the pack that consists of all elements of Views except the first element,
the expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]") is equivalent to:([sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<sentinel_t<*maybe-const*<Const, Views>>,
iterator_t<*maybe-const*<Const, Views>>> && ...) &&([sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")<*maybe-const*<Const, Fs>> && ...)
[🔗](#lib:iter_move,concat_view::iterator)
`friend constexpr decltype(auto) iter_move(const iterator& it) noexcept(see below);
`
[40](#40)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9639)
*Preconditions*: it.*it_*.valueless_by_exception() is false[.](#40.sentence-1)
[41](#41)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9643)
*Effects*: Equivalent to:return std::visit([](const auto& i)-> *concat-rvalue-reference-t*<*maybe-const*<Const, Views>...> {return ranges::iter_move(i); },
it.*it_*);
[42](#42)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9654)
*Remarks*: The exception specification is equivalent to:((is_nothrow_invocable_v<decltype(ranges::iter_move), const iterator_t<*maybe-const*<Const, Views>>&> && is_nothrow_convertible_v<range_rvalue_reference_t<*maybe-const*<Const, Views>>, *concat-rvalue-reference-t*<*maybe-const*<Const, Views>...>>) &&...)
[🔗](#lib:iter_swap,concat_view::iterator)
`friend constexpr void iter_swap(const iterator& x, const iterator& y) noexcept(see below)
requires see below;
`
[43](#43)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9673)
*Preconditions*: x.*it_*.valueless_by_exception() andy.*it_*.valueless_by_exception() are each false[.](#43.sentence-1)
[44](#44)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9678)
*Effects*: Equivalent to:std::visit([&](const auto& it1, const auto& it2) {if constexpr (is_same_v<decltype(it1), decltype(it2)>) { ranges::iter_swap(it1, it2); } else { ranges::swap(*x, *y); }},
x.*it_*, y.*it_*);
[45](#45)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L9692)
*Remarks*: The exception specification is equivalent to(noexcept(ranges::swap(*x, *y)) && ... && noexcept(ranges::iter_swap(its, its))) where its is a pack of lvalues of typeconst iterator_t<*maybe-const*<Const, Views>> respectively[.](#45.sentence-1)
The expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]") is equivalent to[swappable_with](concept.swappable#concept:swappable_with "18.4.9Concept swappable[concept.swappable]")<iter_reference_t<*iterator*>, iter_reference_t<*iterator*>> &&(... && [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>>>)