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

264 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.join.iterator]
# 25 Ranges library [[ranges]](./#ranges)
## 25.7 Range adaptors [[range.adaptors]](range.adaptors#range.join.iterator)
### 25.7.14 Join view [[range.join]](range.join#iterator)
#### 25.7.14.3 Class template join_view::*iterator* [range.join.iterator]
[🔗](#lib:join_view::iterator)
namespace std::ranges {template<[input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]") V>requires [view](range.view#concept:view "25.4.5Views[range.view]")<V> && [input_range](range.refinements#concept:input_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<V>>template<bool Const>struct join_view<V>::*iterator* {private:using *Parent* = *maybe-const*<Const, join_view>; // *exposition only*using *Base* = *maybe-const*<Const, V>; // *exposition only*using *OuterIter* = iterator_t<*Base*>; // *exposition only*using *InnerIter* = iterator_t<range_reference_t<*Base*>>; // *exposition only*static constexpr bool *ref-is-glvalue* = // *exposition only* is_reference_v<range_reference_t<*Base*>>; *OuterIter* *outer_* = *OuterIter*(); // *exposition only*, present only// if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]") optional<*InnerIter*> *inner_*; // *exposition only**Parent** *parent_* = nullptr; // *exposition only*constexpr void *satisfy*(); // *exposition only*constexpr *OuterIter*& *outer*(); // *exposition only*constexpr const *OuterIter*& *outer*() const; // *exposition only*constexpr *iterator*(*Parent*& parent, *OuterIter* outer)requires [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<*Base*>; // *exposition only*constexpr explicit *iterator*(*Parent*& parent)requires (![forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<*Base*>); // *exposition only*public:using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = range_value_t<range_reference_t<*Base*>>; using difference_type = *see below*; *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<V>, *OuterIter*> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<iterator_t<*InnerRng*>, *InnerIter*>; constexpr decltype(auto) operator*() const { return ***inner_*; }constexpr *InnerIter* operator->() constrequires [*has-arrow*](range.utility.helpers#concept:has-arrow "25.5.2Helper concepts[range.utility.helpers]")<*InnerIter*> && [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]")<*InnerIter*>; constexpr *iterator*& operator++(); constexpr void operator++(int); constexpr *iterator* operator++(int)requires *ref-is-glvalue* && [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<*Base*> &&[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<*Base*>>; constexpr *iterator*& operator--()requires *ref-is-glvalue* && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<*Base*> &&[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<*Base*>> &&[common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<*Base*>>; constexpr *iterator* operator--(int)requires *ref-is-glvalue* && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<*Base*> &&[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<*Base*>> &&[common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<*Base*>>; friend constexpr bool operator==(const *iterator*& x, const *iterator*& y)requires *ref-is-glvalue* && [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<*Base*> &&[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<iterator_t<range_reference_t<*Base*>>>; friend constexpr decltype(auto) iter_move(const *iterator*& i)noexcept(noexcept(ranges::iter_move(*i.*inner_*))) {return ranges::iter_move(*i.*inner_*); }friend constexpr void iter_swap(const *iterator*& x, const *iterator*& y)noexcept(noexcept(ranges::iter_swap(*x.*inner_*, *y.*inner_*)))requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<*InnerIter*>; };}
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6843)
*iterator*::iterator_concept is defined as follows:
- [(1.1)](#1.1)
If *ref-is-glvalue* is true, *Base* models [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]"), and range_reference_t<*Base*> models
both [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]") and [common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]"),
then iterator_concept denotes bidirectional_iterator_tag[.](#1.1.sentence-1)
- [(1.2)](#1.2)
Otherwise, if *ref-is-glvalue* is true and *Base* and range_reference_t<*Base*> each model [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]"), then iterator_concept denotes forward_iterator_tag[.](#1.2.sentence-1)
- [(1.3)](#1.3)
Otherwise, iterator_concept denotes input_iterator_tag[.](#1.3.sentence-1)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6858)
The member [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]") iterator_category is defined
if and only if *ref-is-glvalue* is true,*Base* models [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]"), andrange_reference_t<*Base*> models [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")[.](#2.sentence-1)
In that case,*iterator*::iterator_category is defined as follows:
- [(2.1)](#2.1)
Let *OUTERC* denote iterator_traits<iterator_t<*Base*>>::iterator_category, and
let *INNERC* denote iterator_traits<iterator_t<range_reference_t<*Base*>>>::iterator_category[.](#2.1.sentence-1)
- [(2.2)](#2.2)
If *OUTERC* and *INNERC* each model [derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<bidirectional_iterator_tag> and range_reference_t<*Base*> models [common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]"), iterator_category denotes bidirectional_iterator_tag[.](#2.2.sentence-1)
- [(2.3)](#2.3)
Otherwise, if *OUTERC* and *INNERC* each model [derived_from](concept.derived#concept:derived_from "18.4.3Concept derived_­from[concept.derived]")<forward_iterator_tag>, iterator_category denotes forward_iterator_tag[.](#2.3.sentence-1)
- [(2.4)](#2.4)
Otherwise, iterator_category denotes input_iterator_tag[.](#2.4.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6883)
*iterator*::difference_type denotes the type:common_type_t< range_difference_t<*Base*>,
range_difference_t<range_reference_t<*Base*>>>
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6891)
join_view iterators use the *satisfy* function to skip over
empty inner ranges[.](#4.sentence-1)
[🔗](#lib:outer,join_view::iterator)
`constexpr OuterIter& outer();
constexpr const OuterIter& outer() const;
`
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6902)
*Returns*: *outer_* if *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]");
otherwise, **parent_*->*outer_*[.](#5.sentence-1)
[🔗](#lib:satisfy,join_view::iterator)
`constexpr void satisfy();
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6914)
*Effects*: Equivalent to:auto update_inner = [this](const iterator_t<*Base*>& x) -> auto&& {if constexpr (*ref-is-glvalue*) // *x is a referencereturn *x; elsereturn *parent_*->*inner_*.*emplace-deref*(x);};
for (; *outer*() != ranges::end(*parent_*->*base_*); ++*outer*()) {auto&& inner = update_inner(*outer*()); *inner_* = ranges::begin(inner); if (**inner_* != ranges::end(inner))return;}if constexpr (*ref-is-glvalue*)*inner_*.reset();
[🔗](#lib:join_view::iterator,constructor)
`constexpr iterator(Parent& parent, OuterIter outer)
requires [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<Base>;
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6943)
*Effects*: Initializes *outer_* with std::move(outer) and*parent_* with addressof(parent); then calls *satisfy*()[.](#7.sentence-1)
[🔗](#lib:join_view::iterator,constructor_)
`constexpr explicit iterator(Parent& parent)
requires (![forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<Base>);
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6956)
*Effects*: Initializes *parent_* with addressof(parent);
then calls *satisfy*()[.](#8.sentence-1)
[🔗](#lib:join_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<V>, OuterIter> &&
[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<iterator_t<InnerRng>, InnerIter>;
`
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6971)
*Effects*: Initializes *outer_* with std::move(i.*outer_*),*inner_* with std::move(i.*inner_*), and*parent_* with i.*parent_*[.](#9.sentence-1)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6977)
[*Note [1](#note-1)*:
Const can only be true when *Base* models [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")[.](#10.sentence-1)
— *end note*]
[🔗](#lib:operator-%3e,join_view::iterator)
`constexpr InnerIter operator->() const
requires [has-arrow](range.utility.helpers#concept:has-arrow "25.5.2Helper concepts[range.utility.helpers]")<InnerIter> && [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]")<InnerIter>;
`
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L6991)
*Effects*: Equivalent to: return **inner_*;
[🔗](#lib:operator++,join_view::iterator)
`constexpr iterator& operator++();
`
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7002)
Let *inner-range* be:
- [(12.1)](#12.1)
If *ref-is-glvalue* is true, **outer*()[.](#12.1.sentence-1)
- [(12.2)](#12.2)
Otherwise, **parent_*->*inner_*[.](#12.2.sentence-1)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7009)
*Effects*: Equivalent to:if (++**inner_* == ranges::end(*as-lvalue*(*inner-range*))) {++*outer*(); *satisfy*();}return *this;
[🔗](#lib:operator++,join_view::iterator_)
`constexpr void operator++(int);
`
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7027)
*Effects*: Equivalent to: ++*this[.](#14.sentence-1)
[🔗](#lib:operator++,join_view::iterator__)
`constexpr iterator operator++(int)
requires ref-is-glvalue && [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<Base> &&
[forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<Base>>;
`
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7040)
*Effects*: Equivalent to:auto tmp = *this;++*this;return tmp;
[🔗](#lib:operator--,join_view::iterator)
`constexpr iterator& operator--()
requires ref-is-glvalue && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<Base> &&
[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<Base>> &&
[common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<Base>>;
`
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7059)
*Effects*: Equivalent to:if (*outer_* == ranges::end(*parent_*->*base_*))*inner_* = ranges::end(*as-lvalue*(*--*outer_*));while (**inner_* == ranges::begin(*as-lvalue*(**outer_*)))**inner_* = ranges::end(*as-lvalue*(*--*outer_*));--**inner_*;return *this;
[🔗](#lib:operator--,join_view::iterator_)
`constexpr iterator operator--(int)
requires ref-is-glvalue && [bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<Base> &&
[bidirectional_range](range.refinements#concept:bidirectional_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<Base>> &&
[common_range](range.refinements#concept:common_range "25.4.6Other range refinements[range.refinements]")<range_reference_t<Base>>;
`
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7081)
*Effects*: Equivalent to:auto tmp = *this;--*this;return tmp;
[🔗](#lib:operator==,join_view::iterator)
`friend constexpr bool operator==(const iterator& x, const iterator& y)
requires ref-is-glvalue && [forward_range](range.refinements#concept:forward_range "25.4.6Other range refinements[range.refinements]")<Base> &&
[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<iterator_t<range_reference_t<Base>>>;
`
[18](#18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7099)
*Effects*: Equivalent to:return x.*outer_* == y.*outer_* && x.*inner_* == y.*inner_*;
[🔗](#lib:iter_swap,join_view::iterator)
`friend constexpr void iter_swap(const iterator& x, const iterator& y)
noexcept(noexcept(ranges::iter_swap(*x.inner_, *y.inner_)))
requires [indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4Concept indirectly_­swappable[alg.req.ind.swap]")<InnerIter>;
`
[19](#19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/ranges.tex#L7113)
*Effects*: Equivalent to: ranges::iter_swap(*x.*inner_*, *y.*inner_*);