From Jason Turner

[range.iter.ops]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp93q2ylcl/{from.md → to.md} +183 -0
tmp/tmp93q2ylcl/{from.md → to.md} RENAMED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Range iterator operations <a id="range.iter.ops">[[range.iter.ops]]</a>
2
+
3
+ The library includes the function templates `ranges::advance`,
4
+ `ranges::distance`, `ranges::next`, and `ranges::prev` to manipulate
5
+ iterators. These operations adapt to the set of operators provided by
6
+ each iterator category to provide the most efficient implementation
7
+ possible for a concrete iterator type.
8
+
9
+ [*Example 1*: `ranges::advance` uses the `+` operator to move a
10
+ `random_access_iterator` forward `n` steps in constant time. For an
11
+ iterator type that does not model `random_access_iterator`,
12
+ `ranges::advance` instead performs `n` individual increments with the
13
+ `++` operator. — *end example*]
14
+
15
+ The function templates defined in this subclause are not found by
16
+ argument-dependent name lookup [[basic.lookup.argdep]]. When found by
17
+ unqualified [[basic.lookup.unqual]] name lookup for the
18
+ *postfix-expression* in a function call [[expr.call]], they inhibit
19
+ argument-dependent name lookup.
20
+
21
+ [*Example 2*:
22
+
23
+ ``` cpp
24
+ void foo() {
25
+ using namespace std::ranges;
26
+ std::vector<int> vec{1,2,3};
27
+ distance(begin(vec), end(vec)); // #1
28
+ }
29
+ ```
30
+
31
+ The function call expression at `#1` invokes `std::ranges::distance`,
32
+ not `std::distance`, despite that (a) the iterator type returned from
33
+ `begin(vec)` and `end(vec)` may be associated with namespace `std` and
34
+ (b) `std::distance` is more specialized ([[temp.func.order]]) than
35
+ `std::ranges::distance` since the former requires its first two
36
+ parameters to have the same type.
37
+
38
+ — *end example*]
39
+
40
+ The number and order of deducible template parameters for the function
41
+ templates defined in this subclause is unspecified, except where
42
+ explicitly stated otherwise.
43
+
44
+ #### `ranges::advance` <a id="range.iter.op.advance">[[range.iter.op.advance]]</a>
45
+
46
+ ``` cpp
47
+ template<input_or_output_iterator I>
48
+ constexpr void ranges::advance(I& i, iter_difference_t<I> n);
49
+ ```
50
+
51
+ *Preconditions:* If `I` does not model `bidirectional_iterator`, `n` is
52
+ not negative.
53
+
54
+ *Effects:*
55
+
56
+ - If `I` models `random_access_iterator`, equivalent to `i += n`.
57
+ - Otherwise, if `n` is non-negative, increments `i` by `n`.
58
+ - Otherwise, decrements `i` by `-n`.
59
+
60
+ ``` cpp
61
+ template<input_or_output_iterator I, sentinel_for<I> S>
62
+ constexpr void ranges::advance(I& i, S bound);
63
+ ```
64
+
65
+ *Preconditions:* \[`i`, `bound`) denotes a range.
66
+
67
+ *Effects:*
68
+
69
+ - If `I` and `S` model `assignable_from<I&, S>`, equivalent to
70
+ `i = std::move(bound)`.
71
+ - Otherwise, if `S` and `I` model `sized_sentinel_for<S, I>`, equivalent
72
+ to `ranges::advance(i, bound - i)`.
73
+ - Otherwise, while `bool(i != bound)` is `true`, increments `i`.
74
+
75
+ ``` cpp
76
+ template<input_or_output_iterator I, sentinel_for<I> S>
77
+ constexpr iter_difference_t<I> ranges::advance(I& i, iter_difference_t<I> n, S bound);
78
+ ```
79
+
80
+ *Preconditions:* If `n > 0`, \[`i`, `bound`) denotes a range. If
81
+ `n == 0`, \[`i`, `bound`) or \[`bound`, `i`) denotes a range. If
82
+ `n < 0`, \[`bound`, `i`) denotes a range, `I` models
83
+ `bidirectional_iterator`, and `I` and `S` model `same_as<I, S>`.
84
+
85
+ *Effects:*
86
+
87
+ - If `S` and `I` model `sized_sentinel_for<S, I>`:
88
+ - If |`n`| ≥ |`bound - i`|, equivalent to `ranges::advance(i, bound)`.
89
+ - Otherwise, equivalent to `ranges::advance(i, n)`.
90
+ - Otherwise,
91
+ - if `n` is non-negative, while `bool(i != bound)` is `true`,
92
+ increments `i` but at most `n` times.
93
+ - Otherwise, while `bool(i != bound)` is `true`, decrements `i` but at
94
+ most `-n` times.
95
+
96
+ *Returns:* `n - `M, where M is the difference between the ending and
97
+ starting positions of `i`.
98
+
99
+ #### `ranges::distance` <a id="range.iter.op.distance">[[range.iter.op.distance]]</a>
100
+
101
+ ``` cpp
102
+ template<input_or_output_iterator I, sentinel_for<I> S>
103
+ constexpr iter_difference_t<I> ranges::distance(I first, S last);
104
+ ```
105
+
106
+ *Preconditions:* \[`first`, `last`) denotes a range, or \[`last`,
107
+ `first`) denotes a range and `S` and `I` model
108
+ `same_as<S, I> && sized_sentinel_for<S, I>`.
109
+
110
+ *Effects:* If `S` and `I` model `sized_sentinel_for<S, I>`, returns
111
+ `(last - first)`; otherwise, returns the number of increments needed to
112
+ get from `first` to `last`.
113
+
114
+ ``` cpp
115
+ template<range R>
116
+ constexpr range_difference_t<R> ranges::distance(R&& r);
117
+ ```
118
+
119
+ *Effects:* If `R` models `sized_range`, equivalent to:
120
+
121
+ ``` cpp
122
+ return static_cast<range_difference_t<R>>(ranges::size(r)); // [range.prim.size]
123
+ ```
124
+
125
+ Otherwise, equivalent to:
126
+
127
+ ``` cpp
128
+ return ranges::distance(ranges::begin(r), ranges::end(r)); // [range.access]
129
+ ```
130
+
131
+ #### `ranges::next` <a id="range.iter.op.next">[[range.iter.op.next]]</a>
132
+
133
+ ``` cpp
134
+ template<input_or_output_iterator I>
135
+ constexpr I ranges::next(I x);
136
+ ```
137
+
138
+ *Effects:* Equivalent to: `++x; return x;`
139
+
140
+ ``` cpp
141
+ template<input_or_output_iterator I>
142
+ constexpr I ranges::next(I x, iter_difference_t<I> n);
143
+ ```
144
+
145
+ *Effects:* Equivalent to: `ranges::advance(x, n); return x;`
146
+
147
+ ``` cpp
148
+ template<input_or_output_iterator I, sentinel_for<I> S>
149
+ constexpr I ranges::next(I x, S bound);
150
+ ```
151
+
152
+ *Effects:* Equivalent to: `ranges::advance(x, bound); return x;`
153
+
154
+ ``` cpp
155
+ template<input_or_output_iterator I, sentinel_for<I> S>
156
+ constexpr I ranges::next(I x, iter_difference_t<I> n, S bound);
157
+ ```
158
+
159
+ *Effects:* Equivalent to: `ranges::advance(x, n, bound); return x;`
160
+
161
+ #### `ranges::prev` <a id="range.iter.op.prev">[[range.iter.op.prev]]</a>
162
+
163
+ ``` cpp
164
+ template<bidirectional_iterator I>
165
+ constexpr I ranges::prev(I x);
166
+ ```
167
+
168
+ *Effects:* Equivalent to: `-``-``x; return x;`
169
+
170
+ ``` cpp
171
+ template<bidirectional_iterator I>
172
+ constexpr I ranges::prev(I x, iter_difference_t<I> n);
173
+ ```
174
+
175
+ *Effects:* Equivalent to: `ranges::advance(x, -n); return x;`
176
+
177
+ ``` cpp
178
+ template<bidirectional_iterator I>
179
+ constexpr I ranges::prev(I x, iter_difference_t<I> n, I bound);
180
+ ```
181
+
182
+ *Effects:* Equivalent to: `ranges::advance(x, -n, bound); return x;`
183
+