From Jason Turner

[range.join.iterator]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpgu2fi295/{from.md → to.md} +252 -0
tmp/tmpgu2fi295/{from.md → to.md} RENAMED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### Class template `join_view::iterator` <a id="range.join.iterator">[[range.join.iterator]]</a>
2
+
3
+ ``` cpp
4
+ namespace std::ranges {
5
+ template<input_range V>
6
+ requires view<V> && input_range<range_reference_t<V>> &&
7
+ (is_reference_v<range_reference_t<V>> ||
8
+ view<range_value_t<V>>)
9
+ template<bool Const>
10
+ struct join_view<V>::iterator {
11
+ private:
12
+ using Parent = // exposition only
13
+ conditional_t<Const, const join_view, join_view>;
14
+ using Base = conditional_t<Const, const V, V>; // exposition only
15
+
16
+ static constexpr bool ref-is-glvalue = // exposition only
17
+ is_reference_v<range_reference_t<Base>>;
18
+
19
+ iterator_t<Base> outer_ = iterator_t<Base>(); // exposition only
20
+ iterator_t<range_reference_t<Base>> inner_ = // exposition only
21
+ iterator_t<range_reference_t<Base>>();
22
+ Parent* parent_ = nullptr; // exposition only
23
+
24
+ constexpr void satisfy(); // exposition only
25
+ public:
26
+ using iterator_concept = see below;
27
+ using iterator_category = see below;
28
+ using value_type = range_value_t<range_reference_t<Base>>;
29
+ using difference_type = see below;
30
+
31
+ iterator() = default;
32
+ constexpr iterator(Parent& parent, iterator_t<Base> outer);
33
+ constexpr iterator(iterator<!Const> i)
34
+ requires Const &&
35
+ convertible_to<iterator_t<V>, iterator_t<Base>> &&
36
+ convertible_to<iterator_t<InnerRng>,
37
+ iterator_t<range_reference_t<Base>>>;
38
+
39
+ constexpr decltype(auto) operator*() const { return *inner_; }
40
+
41
+ constexpr iterator_t<Base> operator->() const
42
+ requires has-arrow<iterator_t<Base>> && copyable<iterator_t<Base>>;
43
+
44
+ constexpr iterator& operator++();
45
+ constexpr void operator++(int);
46
+ constexpr iterator operator++(int)
47
+ requires ref-is-glvalue && forward_range<Base> &&
48
+ forward_range<range_reference_t<Base>>;
49
+
50
+ constexpr iterator& operator--()
51
+ requires ref-is-glvalue && bidirectional_range<Base> &&
52
+ bidirectional_range<range_reference_t<Base>> &&
53
+ common_range<range_reference_t<Base>>;
54
+
55
+ constexpr iterator operator--(int)
56
+ requires ref-is-glvalue && bidirectional_range<Base> &&
57
+ bidirectional_range<range_reference_t<Base>> &&
58
+ common_range<range_reference_t<Base>>;
59
+
60
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
61
+ requires ref-is-glvalue && equality_comparable<iterator_t<Base>> &&
62
+ equality_comparable<iterator_t<range_reference_t<Base>>>;
63
+
64
+ friend constexpr decltype(auto) iter_move(const iterator& i)
65
+ noexcept(noexcept(ranges::iter_move(i.inner_))) {
66
+ return ranges::iter_move(i.inner_);
67
+ }
68
+
69
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
70
+ noexcept(noexcept(ranges::iter_swap(x.inner_, y.inner_)));
71
+ };
72
+ }
73
+ ```
74
+
75
+ `iterator::iterator_concept` is defined as follows:
76
+
77
+ - If *`ref-is-glvalue`* is `true` and *`Base`* and
78
+ `range_reference_t<Base>` each model `bidirectional_range`, then
79
+ `iterator_concept` denotes `bidirectional_iterator_tag`.
80
+ - Otherwise, if *`ref-is-glvalue`* is `true` and *`Base`* and
81
+ `range_reference_t<Base>` each model , then `iterator_concept` denotes
82
+ `forward_iterator_tag`.
83
+ - Otherwise, `iterator_concept` denotes `input_iterator_tag`.
84
+
85
+ `iterator::iterator_category` is defined as follows:
86
+
87
+ - Let *OUTERC* denote
88
+ `iterator_traits<iterator_t<Base>>::iterator_category`, and let
89
+ *INNERC* denote
90
+ `iterator_traits<iterator_t<range_reference_t<Base>>>::iterator_category`.
91
+ - If *`ref-is-glvalue`* is `true` and *OUTERC* and *INNERC* each model
92
+ `derived_from<bidirectional_iterator_tag>`, `iterator_category`
93
+ denotes `bidirectional_iterator_tag`.
94
+ - Otherwise, if *`ref-is-glvalue`* is `true` and *OUTERC* and *INNERC*
95
+ each model `derived_from<forward_iterator_tag>`, `iterator_category`
96
+ denotes `forward_iterator_tag`.
97
+ - Otherwise, if *OUTERC* and *INNERC* each model
98
+ `derived_from<input_iterator_tag>`, `iterator_category` denotes
99
+ `input_iterator_tag`.
100
+ - Otherwise, `iterator_category` denotes `output_iterator_tag`.
101
+
102
+ `iterator::difference_type` denotes the type:
103
+
104
+ ``` cpp
105
+ common_type_t<
106
+ range_difference_t<Base>,
107
+ range_difference_t<range_reference_t<Base>>>
108
+ ```
109
+
110
+ `join_view` iterators use the *`satisfy`* function to skip over empty
111
+ inner ranges.
112
+
113
+ ``` cpp
114
+ constexpr void satisfy(); // exposition only
115
+ ```
116
+
117
+ *Effects:* Equivalent to:
118
+
119
+ ``` cpp
120
+ auto update_inner = [this](range_reference_t<Base> x) -> auto& {
121
+ if constexpr (ref-is-glvalue) // x is a reference
122
+ return x;
123
+ else
124
+ return (parent_->inner_ = views::all(std::move(x)));
125
+ };
126
+
127
+ for (; outer_ != ranges::end(parent_->base_); ++outer_) {
128
+ auto& inner = update_inner(*outer_);
129
+ inner_ = ranges::begin(inner);
130
+ if (inner_ != ranges::end(inner))
131
+ return;
132
+ }
133
+ if constexpr (ref-is-glvalue)
134
+ inner_ = iterator_t<range_reference_t<Base>>();
135
+ ```
136
+
137
+ ``` cpp
138
+ constexpr iterator(Parent& parent, iterator_t<Base> outer);
139
+ ```
140
+
141
+ *Effects:* Initializes *outer\_* with `std::move(outer)` and *parent\_*
142
+ with `addressof(parent)`; then calls *`satisfy`*`()`.
143
+
144
+ ``` cpp
145
+ constexpr iterator(iterator<!Const> i)
146
+ requires Const &&
147
+ convertible_to<iterator_t<V>, iterator_t<Base>> &&
148
+ convertible_to<iterator_t<InnerRng>,
149
+ iterator_t<range_reference_t<Base>>>;
150
+ ```
151
+
152
+ *Effects:* Initializes *outer\_* with `std::move(i.`*`outer_`*`)`,
153
+ *inner\_* with `std::move(i.`*`inner_`*`)`, and *parent\_* with
154
+ `i.`*`parent_`*.
155
+
156
+ ``` cpp
157
+ constexpr iterator_t<Base> operator->() const
158
+ requires has-arrow<iterator_t<Base>> && copyable<iterator_t<Base>>;
159
+ ```
160
+
161
+ *Effects:* Equivalent to `return `*`inner_`*`;`
162
+
163
+ ``` cpp
164
+ constexpr iterator& operator++();
165
+ ```
166
+
167
+ Let *`inner-range`* be:
168
+
169
+ - If *ref-is-glvalue* is `true`, `*`*`outer_`*.
170
+ - Otherwise, *`parent_`*`->`*`inner_`*.
171
+
172
+ *Effects:* Equivalent to:
173
+
174
+ ``` cpp
175
+ auto&& inner_rng = inner-range;
176
+ if (++inner_ == ranges::end(inner_rng)) {
177
+ ++outer_;
178
+ satisfy();
179
+ }
180
+ return *this;
181
+ ```
182
+
183
+ ``` cpp
184
+ constexpr void operator++(int);
185
+ ```
186
+
187
+ *Effects:* Equivalent to: `++*this`.
188
+
189
+ ``` cpp
190
+ constexpr iterator operator++(int)
191
+ requires ref-is-glvalue && forward_range<Base> &&
192
+ forward_range<range_reference_t<Base>>;
193
+ ```
194
+
195
+ *Effects:* Equivalent to:
196
+
197
+ ``` cpp
198
+ auto tmp = *this;
199
+ ++*this;
200
+ return tmp;
201
+ ```
202
+
203
+ ``` cpp
204
+ constexpr iterator& operator--()
205
+ requires ref-is-glvalue && bidirectional_range<Base> &&
206
+ bidirectional_range<range_reference_t<Base>> &&
207
+ common_range<range_reference_t<Base>>;
208
+ ```
209
+
210
+ *Effects:* Equivalent to:
211
+
212
+ ``` cpp
213
+ if (outer_ == ranges::end(parent_->base_))
214
+ inner_ = ranges::end(*--outer_);
215
+ while (inner_ == ranges::begin(*outer_))
216
+ inner_ = ranges::end(*--outer_);
217
+ --inner_;
218
+ return *this;
219
+ ```
220
+
221
+ ``` cpp
222
+ constexpr iterator operator--(int)
223
+ requires ref-is-glvalue && bidirectional_range<Base> &&
224
+ bidirectional_range<range_reference_t<Base>> &&
225
+ common_range<range_reference_t<Base>>;
226
+ ```
227
+
228
+ *Effects:* Equivalent to:
229
+
230
+ ``` cpp
231
+ auto tmp = *this;
232
+ --*this;
233
+ return tmp;
234
+ ```
235
+
236
+ ``` cpp
237
+ friend constexpr bool operator==(const iterator& x, const iterator& y)
238
+ requires ref-is-glvalue && equality_comparable<iterator_t<Base>> &&
239
+ equality_comparable<iterator_t<range_reference_t<Base>>>;
240
+ ```
241
+
242
+ *Effects:* Equivalent to:
243
+ `return x.`*`outer_`*` == y.`*`outer_`*` && x.`*`inner_`*` == y.`*`inner_`*`;`
244
+
245
+ ``` cpp
246
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
247
+ noexcept(noexcept(ranges::iter_swap(x.inner_, y.inner_)));
248
+ ```
249
+
250
+ *Effects:* Equivalent to:
251
+ `return ranges::iter_swap(x.`*`inner_`*`, y.`*`inner_`*`);`
252
+