@@ -63,12 +63,17 @@ class IteratorImpl {
63
63
" methods must know the complete type." );
64
64
}
65
65
66
+ inline const Iter& as_subclass () const {
67
+ return static_cast <const Iter&>(*this );
68
+ }
69
+ inline Iter& as_subclass_mut () { return static_cast <Iter&>(*this ); }
70
+
66
71
public:
67
72
using Item = ItemT;
68
73
69
74
// / Adaptor for use in ranged for loops.
70
75
auto begin () & noexcept {
71
- return __private::IteratorLoop<Iter&>(static_cast <Iter&>(* this ));
76
+ return __private::IteratorLoop<Iter&>(as_subclass_mut ( ));
72
77
}
73
78
// / Adaptor for use in ranged for loops.
74
79
auto end () & noexcept { return __private::IteratorEnd (); }
@@ -78,7 +83,7 @@ class IteratorImpl {
78
83
// / sus::iter::IntoIterator trait implementation.
79
84
Iter&& into_iter() && noexcept { return static_cast <Iter&&>(*this ); }
80
85
81
- // Provided methods.
86
+ // Provided overridable methods.
82
87
83
88
// / Returns the bounds on the remaining length of the iterator.
84
89
// /
@@ -104,9 +109,7 @@ class IteratorImpl {
104
109
// /
105
110
// / The default implementation returns `lower = 0` and `upper = None` which is
106
111
// / correct for any iterator.
107
- virtual SizeHint size_hint () const noexcept {
108
- return SizeHint (0_usize, ::sus::Option<::sus::num::usize>::none ());
109
- }
112
+ virtual SizeHint size_hint () const noexcept ;
110
113
111
114
// / Tests whether all elements of the iterator match a predicate.
112
115
// /
@@ -116,7 +119,7 @@ class IteratorImpl {
116
119
// / from the predicate.
117
120
// /
118
121
// / Returns `true` if the iterator is empty.
119
- bool all (::sus::fn::FnMut<bool (Item)> f) noexcept ;
122
+ virtual bool all (::sus::fn::FnMut<bool (Item)> f) noexcept ;
120
123
121
124
// / Tests whether any elements of the iterator match a predicate.
122
125
// /
@@ -126,7 +129,21 @@ class IteratorImpl {
126
129
// / the predicate.
127
130
// /
128
131
// / Returns `false` if the iterator is empty.
129
- bool any (::sus::fn::FnMut<bool (Item)> f) noexcept ;
132
+ virtual bool any (::sus::fn::FnMut<bool (Item)> f) noexcept ;
133
+
134
+ // / Consumes the iterator, and returns the number of elements that were in
135
+ // / it.
136
+ // /
137
+ // / The function walks the iterator until it sees an Option holding #None.
138
+ // /
139
+ // / # Safety
140
+ // /
141
+ // / If the `usize` type does not have trapping arithmetic enabled, and the
142
+ // / iterator has more than `usize::MAX` elements in it, the value will wrap
143
+ // / and be incorrect. Otherwise, `usize` will catch overflow and panic.
144
+ virtual ::sus::num::usize count () noexcept ;
145
+
146
+ // Provided final methods.
130
147
131
148
// / Wraps the iterator in a new iterator that is trivially relocatable.
132
149
// /
@@ -145,18 +162,6 @@ class IteratorImpl {
145
162
auto box () && noexcept
146
163
requires(!::sus::mem::relocate_by_memcpy<Iter>);
147
164
148
- // / Consumes the iterator, and returns the number of elements that were in
149
- // / it.
150
- // /
151
- // / The function walks the iterator until it sees an Option holding #None.
152
- // /
153
- // / # Safety
154
- // /
155
- // / If the `usize` type does not have trapping arithmetic enabled, and the
156
- // / iterator has more than `usize::MAX` elements in it, the value will wrap
157
- // / and be incorrect. Otherwise, `usize` will catch overflow and panic.
158
- ::sus::num::usize count () noexcept ;
159
-
160
165
// / Creates an iterator which uses a closure to map each element to another
161
166
// / type.
162
167
// /
@@ -176,8 +181,16 @@ class IteratorImpl {
176
181
pred) && noexcept
177
182
requires(::sus::mem::relocate_by_memcpy<Iter>);
178
183
179
- auto reverse () && noexcept
180
- requires(::sus::mem::relocate_by_memcpy<Iter>);
184
+ // / Reverses an iterator's direction.
185
+ // /
186
+ // / Usually, iterators iterate from front to back. After using `rev()`, an
187
+ // / iterator will instead iterate from back to front.
188
+ // /
189
+ // / This is only possible if the iterator has an end, so `rev()` only works on
190
+ // / `DoubleEndedIterator`s.
191
+ auto rev () && noexcept
192
+ requires(::sus::mem::relocate_by_memcpy<Iter> &&
193
+ ::sus::iter::DoubleEndedIterator<Iter, Item>);
181
194
182
195
// / Transforms an iterator into a collection.
183
196
// /
@@ -219,11 +232,15 @@ class IteratorImpl {
219
232
// TODO: cloned().
220
233
};
221
234
235
+ template <class Iter , class Item >
236
+ SizeHint IteratorImpl<Iter, Item>::size_hint() const noexcept {
237
+ return SizeHint (0_usize, ::sus::Option<::sus::num::usize>::none ());
238
+ }
239
+
222
240
template <class Iter , class Item >
223
241
bool IteratorImpl<Iter, Item>::all(::sus::fn::FnMut<bool (Item)> f) noexcept {
224
- // TODO: If constexpr(I::all() exists) then call that instead.
225
242
while (true ) {
226
- Option<Item> item = static_cast <Iter&>(* this ).next ();
243
+ Option<Item> item = as_subclass_mut ( ).next ();
227
244
if (item.is_none ()) return true ;
228
245
// SAFETY: `item` was checked to hold Some already.
229
246
if (!f (item.take ().unwrap_unchecked (::sus::marker::unsafe_fn)))
@@ -233,23 +250,14 @@ bool IteratorImpl<Iter, Item>::all(::sus::fn::FnMut<bool(Item)> f) noexcept {
233
250
234
251
template <class Iter , class Item >
235
252
bool IteratorImpl<Iter, Item>::any(::sus::fn::FnMut<bool (Item)> f) noexcept {
236
- // TODO: If constexpr(I::any() exists) then call that instead.
237
253
while (true ) {
238
- Option<Item> item = static_cast <Iter&>(* this ).next ();
254
+ Option<Item> item = as_subclass_mut ( ).next ();
239
255
if (item.is_none ()) return false ;
240
256
// SAFETY: `item` was checked to hold Some already.
241
257
if (f (item.take ().unwrap_unchecked (::sus::marker::unsafe_fn))) return true ;
242
258
}
243
259
}
244
260
245
- template <class Iter , class Item >
246
- ::sus::num::usize IteratorImpl<Iter, Item>::count() noexcept {
247
- // TODO: If constexpr(I::count() exists) then call that instead.
248
- auto c = 0_usize;
249
- while (static_cast <Iter&>(*this ).next ().is_some ()) c += 1_usize;
250
- return c;
251
- }
252
-
253
261
template <class Iter , class Item >
254
262
auto IteratorImpl<Iter, Item>::box() && noexcept
255
263
requires (!::sus::mem::relocate_by_memcpy<Iter>)
@@ -260,6 +268,13 @@ auto IteratorImpl<Iter, Item>::box() && noexcept
260
268
return BoxedIterator::with (static_cast <Iter&&>(*this ));
261
269
}
262
270
271
+ template <class Iter , class Item >
272
+ ::sus::num::usize IteratorImpl<Iter, Item>::count() noexcept {
273
+ auto c = 0_usize;
274
+ while (as_subclass_mut ().next ().is_some ()) c += 1_usize;
275
+ return c;
276
+ }
277
+
263
278
template <class Iter , class Item >
264
279
template <class MapFn , int &..., class R , class MapFnMut >
265
280
requires (::sus::construct::Into<MapFn, MapFnMut> && !std::is_void_v<R>)
@@ -285,8 +300,9 @@ auto IteratorImpl<Iter, Item>::filter(
285
300
}
286
301
287
302
template <class Iter , class Item >
288
- auto IteratorImpl<Iter, Item>::reverse() && noexcept
289
- requires (::sus::mem::relocate_by_memcpy<Iter>)
303
+ auto IteratorImpl<Iter, Item>::rev() && noexcept
304
+ requires (::sus::mem::relocate_by_memcpy<Iter> &&
305
+ ::sus::iter::DoubleEndedIterator<Iter, Item>)
290
306
{
291
307
using Sized = SizedIteratorType<Iter>::type;
292
308
using Reverse = Reverse<Sized>;
0 commit comments