366 lines
22 KiB
Markdown
366 lines
22 KiB
Markdown
[iterators.common]
|
||
|
||
# 24 Iterators library [[iterators]](./#iterators)
|
||
|
||
## 24.5 Iterator adaptors [[predef.iterators]](predef.iterators#iterators.common)
|
||
|
||
### 24.5.5 Common iterators [iterators.common]
|
||
|
||
#### [24.5.5.1](#common.iterator) Class template common_iterator [[common.iterator]](common.iterator)
|
||
|
||
[1](#common.iterator-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5414)
|
||
|
||
Class template common_iterator is an iterator/sentinel adaptor that is
|
||
capable of representing a non-common range of elements (where the types of the
|
||
iterator and sentinel differ) as a common range (where they are the same)[.](#common.iterator-1.sentence-1)
|
||
|
||
It
|
||
does this by holding either an iterator or a sentinel, and implementing the
|
||
equality comparison operators appropriately[.](#common.iterator-1.sentence-2)
|
||
|
||
[2](#common.iterator-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5421)
|
||
|
||
[*Note [1](#common.iterator-note-1)*:
|
||
|
||
The common_iterator type is useful for interfacing with legacy
|
||
code that expects the begin and end of a range to have the same type[.](#common.iterator-2.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[3](#common.iterator-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5427)
|
||
|
||
[*Example [1](#common.iterator-example-1)*: template<class ForwardIterator>void fun(ForwardIterator begin, ForwardIterator end);
|
||
|
||
list<int> s;// populate the list susing CI = common_iterator<counted_iterator<list<int>::iterator>, default_sentinel_t>;// call fun on a range of 10 ints fun(CI(counted_iterator(s.begin(), 10)), CI(default_sentinel)); â *end example*]
|
||
|
||
[ð](#lib:common_iterator)
|
||
|
||
namespace std {template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6 Concept input_or_output_iterator [iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S>requires (<I, S> && [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<I>)class common_iterator {public:constexpr common_iterator() requires [default_initializable](concept.default.init#concept:default_initializable "18.4.12 Concept default_initializable [concept.default.init]")<I> = default; constexpr common_iterator(I i); constexpr common_iterator(S s); template<class I2, class S2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const S2&, S>constexpr common_iterator(const common_iterator<I2, S2>& x); template<class I2, class S2>requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const S2&, S> &&[assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_from [concept.assignable]")<I&, const I2&> && [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_from [concept.assignable]")<S&, const S2&>constexpr common_iterator& operator=(const common_iterator<I2, S2>& x); constexpr decltype(auto) operator*(); constexpr decltype(auto) operator*() constrequires [*dereferenceable*](iterator.synopsis#concept:dereferenceable "24.2 Header <iterator> synopsis [iterator.synopsis]")<const I>; constexpr auto operator->() constrequires *see below*; constexpr common_iterator& operator++(); constexpr decltype(auto) operator++(int); template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S2>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<S, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S2>requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<S, I2> && [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<I, I2>friend constexpr bool operator==(const common_iterator& x, const common_iterator<I2, S2>& y); template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I> I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I> S2>requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<S, I2>friend constexpr iter_difference_t<I2> operator-(const common_iterator& x, const common_iterator<I2, S2>& y); friend constexpr decltype(auto) iter_move(const common_iterator& i)noexcept(noexcept(ranges::iter_move(declval<const I&>())))requires [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]")<I>; template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<I> I2, class S2>friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>()))); private: variant<I, S> v_; // *exposition only*}; template<class I, class S>struct incrementable_traits<common_iterator<I, S>> {using difference_type = iter_difference_t<I>; }; template<[input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]") I, class S>struct iterator_traits<common_iterator<I, S>> {using iterator_concept = *see below*; using iterator_category = *see below*; // not always presentusing value_type = iter_value_t<I>; using difference_type = iter_difference_t<I>; using pointer = *see below*; using reference = iter_reference_t<I>; };}
|
||
|
||
#### [24.5.5.2](#common.iter.types) Associated types [[common.iter.types]](common.iter.types)
|
||
|
||
[1](#common.iter.types-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5513)
|
||
|
||
The nested [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") iterator_category of
|
||
the specialization of iterator_traits for common_iterator<I, S> is defined if and only if iter_difference_t<I> is an integral type[.](#common.iter.types-1.sentence-1)
|
||
|
||
In that case,iterator_category denotes forward_iterator_tag if
|
||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") iterator_traits<I>::iterator_category is valid and denotes a type that
|
||
models [derived_from](concept.derived#concept:derived_from "18.4.3 Concept derived_from [concept.derived]")<forward_iterator_tag>;
|
||
otherwise it denotes input_iterator_tag[.](#common.iter.types-1.sentence-2)
|
||
|
||
[2](#common.iter.types-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5524)
|
||
|
||
The remaining nested [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")*s* of the specialization ofiterator_traits for common_iterator<I, S> are defined as follows:
|
||
|
||
- [(2.1)](#common.iter.types-2.1)
|
||
|
||
iterator_concept denotes forward_iterator_tag if I models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]");
|
||
otherwise it denotes input_iterator_tag[.](#common.iter.types-2.1.sentence-1)
|
||
|
||
- [(2.2)](#common.iter.types-2.2)
|
||
|
||
Let a denote an lvalue of type const common_iterator<I, S>[.](#common.iter.types-2.2.sentence-1)
|
||
If the expression a.operator->() is well-formed,
|
||
then pointer denotes decltype(a.operator->())[.](#common.iter.types-2.2.sentence-2)
|
||
Otherwise, pointer denotes void[.](#common.iter.types-2.2.sentence-3)
|
||
|
||
#### [24.5.5.3](#common.iter.const) Constructors and conversions [[common.iter.const]](common.iter.const)
|
||
|
||
[ð](#lib:common_iterator,constructor)
|
||
|
||
`constexpr common_iterator(I i);
|
||
`
|
||
|
||
[1](#common.iter.const-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5548)
|
||
|
||
*Effects*: Initializes v_ as if by v_{in_place_type<I>, std::move(i)}[.](#common.iter.const-1.sentence-1)
|
||
|
||
[ð](#lib:common_iterator,constructor_)
|
||
|
||
`constexpr common_iterator(S s);
|
||
`
|
||
|
||
[2](#common.iter.const-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5559)
|
||
|
||
*Effects*: Initializes v_ as if byv_{in_place_type<S>, std::move(s)}[.](#common.iter.const-2.sentence-1)
|
||
|
||
[ð](#lib:common_iterator,constructor__)
|
||
|
||
`template<class I2, class S2>
|
||
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const S2&, S>
|
||
constexpr common_iterator(const common_iterator<I2, S2>& x);
|
||
`
|
||
|
||
[3](#common.iter.const-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5573)
|
||
|
||
*Hardened preconditions*: x.v_.valueless_by_exception() is false[.](#common.iter.const-3.sentence-1)
|
||
|
||
[4](#common.iter.const-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5577)
|
||
|
||
*Effects*: Initializes v_ as if byv_{in_place_index<i>, get<i>(x.v_)},
|
||
where i is x.v_.index()[.](#common.iter.const-4.sentence-1)
|
||
|
||
[ð](#lib:operator=,common_iterator)
|
||
|
||
`template<class I2, class S2>
|
||
requires [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const I2&, I> && [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<const S2&, S> &&
|
||
[assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_from [concept.assignable]")<I&, const I2&> && [assignable_from](concept.assignable#concept:assignable_from "18.4.8 Concept assignable_from [concept.assignable]")<S&, const S2&>
|
||
constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
|
||
`
|
||
|
||
[5](#common.iter.const-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5593)
|
||
|
||
*Hardened preconditions*: x.v_.valueless_by_exception() is false[.](#common.iter.const-5.sentence-1)
|
||
|
||
[6](#common.iter.const-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5597)
|
||
|
||
*Effects*: Equivalent to:
|
||
|
||
- [(6.1)](#common.iter.const-6.1)
|
||
|
||
If v_.index() == x.v_.index(), thenget<i>(v_) = get<i>(x.v_)[.](#common.iter.const-6.1.sentence-1)
|
||
|
||
- [(6.2)](#common.iter.const-6.2)
|
||
|
||
Otherwise, v_.emplace<i>(get<i>(x.v_))[.](#common.iter.const-6.2.sentence-1)
|
||
|
||
where i is x.v_.index()[.](#common.iter.const-6.sentence-2)
|
||
|
||
[7](#common.iter.const-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5608)
|
||
|
||
*Returns*: *this[.](#common.iter.const-7.sentence-1)
|
||
|
||
#### [24.5.5.4](#common.iter.access) Accessors [[common.iter.access]](common.iter.access)
|
||
|
||
[ð](#lib:operator*,common_iterator)
|
||
|
||
`constexpr decltype(auto) operator*();
|
||
constexpr decltype(auto) operator*() const
|
||
requires [dereferenceable](iterator.synopsis#concept:dereferenceable "24.2 Header <iterator> synopsis [iterator.synopsis]")<const I>;
|
||
`
|
||
|
||
[1](#common.iter.access-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5623)
|
||
|
||
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.access-1.sentence-1)
|
||
|
||
[2](#common.iter.access-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5627)
|
||
|
||
*Effects*: Equivalent to: return *get<I>(v_);
|
||
|
||
[ð](#lib:operator-%3e,common_iterator)
|
||
|
||
`constexpr auto operator->() const
|
||
requires see below;
|
||
`
|
||
|
||
[3](#common.iter.access-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5639)
|
||
|
||
The expression in the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is equivalent to:[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_readable [iterator.concept.readable]")<const I> &&(requires(const I& i) { i.operator->(); } || is_reference_v<iter_reference_t<I>> ||[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<I>, iter_reference_t<I>>)
|
||
|
||
[4](#common.iter.access-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5648)
|
||
|
||
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.access-4.sentence-1)
|
||
|
||
[5](#common.iter.access-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5652)
|
||
|
||
*Effects*:
|
||
|
||
- [(5.1)](#common.iter.access-5.1)
|
||
|
||
If I is a pointer type or if the expressionget<I>(v_).operator->() is
|
||
well-formed, equivalent to: return get<I>(v_);
|
||
|
||
- [(5.2)](#common.iter.access-5.2)
|
||
|
||
Otherwise, if iter_reference_t<I> is a reference type, equivalent to:auto&& tmp = *get<I>(v_);return addressof(tmp);
|
||
|
||
- [(5.3)](#common.iter.access-5.3)
|
||
|
||
Otherwise, equivalent to:return *proxy*(*get<I>(v_)); where*proxy* is the exposition-only class:class *proxy* { iter_value_t<I> keep_; constexpr *proxy*(iter_reference_t<I>&& x): keep_(std::move(x)) {}public:constexpr const iter_value_t<I>* operator->() const noexcept {return addressof(keep_); }};
|
||
|
||
#### [24.5.5.5](#common.iter.nav) Navigation [[common.iter.nav]](common.iter.nav)
|
||
|
||
[ð](#lib:operator++,common_iterator)
|
||
|
||
`constexpr common_iterator& operator++();
|
||
`
|
||
|
||
[1](#common.iter.nav-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5693)
|
||
|
||
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.nav-1.sentence-1)
|
||
|
||
[2](#common.iter.nav-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5697)
|
||
|
||
*Effects*: Equivalent to ++get<I>(v_)[.](#common.iter.nav-2.sentence-1)
|
||
|
||
[3](#common.iter.nav-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5701)
|
||
|
||
*Returns*: *this[.](#common.iter.nav-3.sentence-1)
|
||
|
||
[ð](#lib:operator++,common_iterator_)
|
||
|
||
`constexpr decltype(auto) operator++(int);
|
||
`
|
||
|
||
[4](#common.iter.nav-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5712)
|
||
|
||
*Hardened preconditions*: holds_alternative<I>(v_) is true[.](#common.iter.nav-4.sentence-1)
|
||
|
||
[5](#common.iter.nav-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5716)
|
||
|
||
*Effects*: If I models [forward_iterator](iterator.concept.forward#concept:forward_iterator "24.3.4.11 Concept forward_iterator [iterator.concept.forward]"), equivalent to:common_iterator tmp = *this;++*this;return tmp;
|
||
|
||
Otherwise, ifrequires(I& i) { { *i++ } -> [*can-reference*](iterator.synopsis#concept:can-reference "24.2 Header <iterator> synopsis [iterator.synopsis]"); } is true or[indirectly_readable](iterator.concept.readable#concept:indirectly_readable "24.3.4.2 Concept indirectly_readable [iterator.concept.readable]")<I> && [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<iter_value_t<I>, iter_reference_t<I>> &&[move_constructible](concept.moveconstructible#concept:move_constructible "18.4.13 Concept move_constructible [concept.moveconstructible]")<iter_value_t<I>> is false,
|
||
equivalent to:return get<I>(v_)++;
|
||
|
||
Otherwise, equivalent to:*postfix-proxy* p(**this);++*this;return p; where *postfix-proxy* is the exposition-only class:class *postfix-proxy* { iter_value_t<I> keep_; constexpr *postfix-proxy*(iter_reference_t<I>&& x): keep_(std::forward<iter_reference_t<I>>(x)) {}public:constexpr const iter_value_t<I>& operator*() const noexcept {return keep_; }};
|
||
|
||
#### [24.5.5.6](#common.iter.cmp) Comparisons [[common.iter.cmp]](common.iter.cmp)
|
||
|
||
[ð](#lib:operator==,common_iterator)
|
||
|
||
`template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S2>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<S, I2>
|
||
friend constexpr bool operator==(
|
||
const common_iterator& x, const common_iterator<I2, S2>& y);
|
||
`
|
||
|
||
[1](#common.iter.cmp-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5767)
|
||
|
||
*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-1.sentence-1)
|
||
|
||
[2](#common.iter.cmp-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5772)
|
||
|
||
*Returns*: true if i == j,
|
||
and otherwise get<i>(x.v_) == get<j>(y.v_),
|
||
where i is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-2.sentence-1)
|
||
|
||
[ð](#lib:operator==,common_iterator_)
|
||
|
||
`template<class I2, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<I> S2>
|
||
requires [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7 Concept sentinel_for [iterator.concept.sentinel]")<S, I2> && [equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<I, I2>
|
||
friend constexpr bool operator==(
|
||
const common_iterator& x, const common_iterator<I2, S2>& y);
|
||
`
|
||
|
||
[3](#common.iter.cmp-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5788)
|
||
|
||
*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-3.sentence-1)
|
||
|
||
[4](#common.iter.cmp-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5793)
|
||
|
||
*Returns*: true if i and j are each 1, and otherwiseget<i>(x.v_) == get<j>(y.v_), wherei is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-4.sentence-1)
|
||
|
||
[ð](#lib:operator-,common_iterator)
|
||
|
||
`template<[sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I> I2, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<I> S2>
|
||
requires [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8 Concept sized_sentinel_for [iterator.concept.sizedsentinel]")<S, I2>
|
||
friend constexpr iter_difference_t<I2> operator-(
|
||
const common_iterator& x, const common_iterator<I2, S2>& y);
|
||
`
|
||
|
||
[5](#common.iter.cmp-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5809)
|
||
|
||
*Hardened preconditions*: x.v_.valueless_by_exception() and y.v_.valueless_by_exception() are each false[.](#common.iter.cmp-5.sentence-1)
|
||
|
||
[6](#common.iter.cmp-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5814)
|
||
|
||
*Returns*: 0 if i and j are each 1, and otherwiseget<i>(x.v_) - get<j>(y.v_), wherei is x.v_.index() and j is y.v_.index()[.](#common.iter.cmp-6.sentence-1)
|
||
|
||
#### [24.5.5.7](#common.iter.cust) Customizations [[common.iter.cust]](common.iter.cust)
|
||
|
||
[ð](#lib:iter_move,common_iterator)
|
||
|
||
`friend constexpr decltype(auto) iter_move(const common_iterator& i)
|
||
noexcept(noexcept(ranges::iter_move(declval<const I&>())))
|
||
requires [input_iterator](iterator.concept.input#concept:input_iterator "24.3.4.9 Concept input_iterator [iterator.concept.input]")<I>;
|
||
`
|
||
|
||
[1](#common.iter.cust-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5831)
|
||
|
||
*Hardened preconditions*: holds_alternative<I>(i.v_) is true[.](#common.iter.cust-1.sentence-1)
|
||
|
||
[2](#common.iter.cust-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5835)
|
||
|
||
*Effects*: Equivalent to: return ranges::iter_move(get<I>(i.v_));
|
||
|
||
[ð](#lib:iter_swap,common_iterator)
|
||
|
||
`template<[indirectly_swappable](alg.req.ind.swap#concept:indirectly_swappable "24.3.7.4 Concept indirectly_swappable [alg.req.ind.swap]")<I> I2, class S2>
|
||
friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
|
||
noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
|
||
`
|
||
|
||
[3](#common.iter.cust-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5848)
|
||
|
||
*Hardened preconditions*: holds_alternative<I>(x.v_) and holds_alternative<I2>(y.v_) are each true[.](#common.iter.cust-3.sentence-1)
|
||
|
||
[4](#common.iter.cust-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L5853)
|
||
|
||
*Effects*: Equivalent to ranges::iter_swap(get<I>(x.v_), get<I2>(y.v_))[.](#common.iter.cust-4.sentence-1)
|