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

295 lines
13 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.iter.ops]
# 24 Iterators library [[iterators]](./#iterators)
## 24.4 Iterator primitives [[iterator.primitives]](iterator.primitives#range.iter.ops)
### 24.4.4 Range iterator operations [range.iter.ops]
#### [24.4.4.1](#general) General [[range.iter.ops.general]](range.iter.ops.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2927)
The library includes the function templatesranges::advance, ranges::distance,ranges::next, and ranges::prev to manipulate iterators[.](#general-1.sentence-1)
These operations adapt to the set of operators
provided by each iterator category to provide the most efficient implementation
possible for a concrete iterator type[.](#general-1.sentence-2)
[*Example [1](#general-example-1)*:
ranges::advance uses the + operator to move a[random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]") forward n steps in constant time[.](#general-1.sentence-3)
For an iterator type that does not model [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]"),ranges::advance instead performs n individual increments with
the ++ operator[.](#general-1.sentence-4)
— *end example*]
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2942)
The entities defined in [range.iter.ops] are
algorithm function objects ([[alg.func.obj]](alg.func.obj "16.3.3.4Algorithm function objects"))[.](#general-2.sentence-1)
#### [24.4.4.2](#range.iter.op.advance) ranges::advance [[range.iter.op.advance]](range.iter.op.advance)
[🔗](#lib:advance)
`template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I>
constexpr void ranges::advance(I& i, iter_difference_t<I> n);
`
[1](#range.iter.op.advance-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2955)
*Preconditions*: If I does not model [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]"),n is not negative[.](#range.iter.op.advance-1.sentence-1)
[2](#range.iter.op.advance-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2960)
*Effects*:
- [(2.1)](#range.iter.op.advance-2.1)
If I models [random_access_iterator](iterator.concept.random.access#concept:random_access_iterator "24.3.4.13Concept random_­access_­iterator[iterator.concept.random.access]"),
equivalent to i += n[.](#range.iter.op.advance-2.1.sentence-1)
- [(2.2)](#range.iter.op.advance-2.2)
Otherwise, if n is non-negative, increments i by n[.](#range.iter.op.advance-2.2.sentence-1)
- [(2.3)](#range.iter.op.advance-2.3)
Otherwise, decrements i by -n[.](#range.iter.op.advance-2.3.sentence-1)
[🔗](#lib:advance_)
`template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S>
constexpr void ranges::advance(I& i, S bound);
`
[3](#range.iter.op.advance-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2978)
*Preconditions*: Either [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<I&, S> || [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I> is modeled, or
[i, bound) denotes a range[.](#range.iter.op.advance-3.sentence-1)
[4](#range.iter.op.advance-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L2983)
*Effects*:
- [(4.1)](#range.iter.op.advance-4.1)
If I and S model [assignable_from](concept.assignable#concept:assignable_from "18.4.8Concept assignable_­from[concept.assignable]")<I&, S>,
equivalent to i = std::move(bound)[.](#range.iter.op.advance-4.1.sentence-1)
- [(4.2)](#range.iter.op.advance-4.2)
Otherwise, if S and I model [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I>,
equivalent to ranges::advance(i, bound - i)[.](#range.iter.op.advance-4.2.sentence-1)
- [(4.3)](#range.iter.op.advance-4.3)
Otherwise, while bool(i != bound) is true,
increments i[.](#range.iter.op.advance-4.3.sentence-1)
[🔗](#lib:advance__)
`template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S>
constexpr iter_difference_t<I> ranges::advance(I& i, iter_difference_t<I> n, S bound);
`
[5](#range.iter.op.advance-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3002)
*Preconditions*: If n > 0, [i, bound) denotes a range[.](#range.iter.op.advance-5.sentence-1)
If n == 0, [i, bound) or [bound, i) denotes a range[.](#range.iter.op.advance-5.sentence-2)
If n < 0, [bound, i) denotes a range,I models [bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]"), andI and S model [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<I, S>[.](#range.iter.op.advance-5.sentence-3)
[6](#range.iter.op.advance-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3010)
*Effects*:
- [(6.1)](#range.iter.op.advance-6.1)
If S and I model [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I>:
* [(6.1.1)](#range.iter.op.advance-6.1.1)
If |n| ≥ |bound - i|,
equivalent to ranges::advance(i, bound)[.](#range.iter.op.advance-6.1.1.sentence-1)
* [(6.1.2)](#range.iter.op.advance-6.1.2)
Otherwise, equivalent to ranges::advance(i, n)[.](#range.iter.op.advance-6.1.2.sentence-1)
- [(6.2)](#range.iter.op.advance-6.2)
Otherwise,
* [(6.2.1)](#range.iter.op.advance-6.2.1)
if n is non-negative,
while bool(i != bound) is true,
increments i but at most n times[.](#range.iter.op.advance-6.2.1.sentence-1)
* [(6.2.2)](#range.iter.op.advance-6.2.2)
Otherwise,
while bool(i != bound) is true,
decrements i but at most -n times[.](#range.iter.op.advance-6.2.2.sentence-1)
[7](#range.iter.op.advance-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3030)
*Returns*: n - M, where M is the difference between
the ending and starting positions of i[.](#range.iter.op.advance-7.sentence-1)
#### [24.4.4.3](#range.iter.op.distance) ranges::distance [[range.iter.op.distance]](range.iter.op.distance)
[🔗](#lib:distance)
`template<class I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S>
requires (![sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<S, I>)
constexpr iter_difference_t<I> ranges::distance(I first, S last);
`
[1](#range.iter.op.distance-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3045)
*Preconditions*: [first, last) denotes a range[.](#range.iter.op.distance-1.sentence-1)
[2](#range.iter.op.distance-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3049)
*Effects*: Increments first until last is reached and
returns the number of increments[.](#range.iter.op.distance-2.sentence-1)
[🔗](#lib:distance_)
`template<class I, [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<decay_t<I>> S>
constexpr iter_difference_t<decay_t<I>> ranges::distance(I&& first, S last);
`
[3](#range.iter.op.distance-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3062)
*Effects*: Equivalent to:if constexpr (!is_array_v<remove_reference_t<I>>)return last - first;elsereturn last - static_cast<decay_t<I>>(first);
[🔗](#lib:distance__)
`template<[range](range.range#concept:range "25.4.2Ranges[range.range]") R>
constexpr range_difference_t<R> ranges::distance(R&& r);
`
[4](#range.iter.op.distance-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3080)
*Effects*: If R models [sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]"), equivalent to:return static_cast<range_difference_t<R>>(ranges::size(r)); // [[range.prim.size]](range.prim.size "25.3.10ranges::size")
Otherwise, equivalent to:return ranges::distance(ranges::begin(r), ranges::end(r)); // [[range.access]](range.access "25.3Range access")
#### [24.4.4.4](#range.iter.op.next) ranges::next [[range.iter.op.next]](range.iter.op.next)
[🔗](#lib:next)
`template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I>
constexpr I ranges::next(I x);
`
[1](#range.iter.op.next-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3101)
*Effects*: Equivalent to: ++x; return x;
[🔗](#lib:next_)
`template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I>
constexpr I ranges::next(I x, iter_difference_t<I> n);
`
[2](#range.iter.op.next-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3113)
*Effects*: Equivalent to: ranges::advance(x, n); return x;
[🔗](#lib:next__)
`template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S>
constexpr I ranges::next(I x, S bound);
`
[3](#range.iter.op.next-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3125)
*Effects*: Equivalent to: ranges::advance(x, bound); return x;
[🔗](#lib:next___)
`template<[input_or_output_iterator](iterator.concept.iterator#concept:input_or_output_iterator "24.3.4.6Concept input_­or_­output_­iterator[iterator.concept.iterator]") I, [sentinel_for](iterator.concept.sentinel#concept:sentinel_for "24.3.4.7Concept sentinel_­for[iterator.concept.sentinel]")<I> S>
constexpr I ranges::next(I x, iter_difference_t<I> n, S bound);
`
[4](#range.iter.op.next-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3137)
*Effects*: Equivalent to: ranges::advance(x, n, bound); return x;
#### [24.4.4.5](#range.iter.op.prev) ranges::prev [[range.iter.op.prev]](range.iter.op.prev)
[🔗](#lib:prev)
`template<[bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") I>
constexpr I ranges::prev(I x);
`
[1](#range.iter.op.prev-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3150)
*Effects*: Equivalent to: --x; return x;
[🔗](#lib:prev_)
`template<[bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") I>
constexpr I ranges::prev(I x, iter_difference_t<I> n);
`
[2](#range.iter.op.prev-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3162)
*Effects*: Equivalent to: ranges::advance(x, -n); return x;
[🔗](#lib:prev__)
`template<[bidirectional_iterator](iterator.concept.bidir#concept:bidirectional_iterator "24.3.4.12Concept bidirectional_­iterator[iterator.concept.bidir]") I>
constexpr I ranges::prev(I x, iter_difference_t<I> n, I bound);
`
[3](#range.iter.op.prev-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iterators.tex#L3174)
*Effects*: Equivalent to: ranges::advance(x, -n, bound); return x;