Skip to content

Commit 4514fb9

Browse files
committed
Auto merge of #112229 - clarfonthey:range-iter-count, r=dtolnay
Specialize count for range iterators Since `size_hint` is already specialized, it feels apt to specialize `count` as well. Without any specialized version of `ExactSizeIterator::len` or `Step::steps_between`, this feels like a more reliable way of accessing this without having to rely on knowing that `size_hint` is correct. In my case, this is particularly useful to access the `steps_between` implementation for `char` from the standard library without having to compute it manually. I didn't think it was worth modifying the `Step` trait to add a version of `steps_between` that used native overflow checks since this is just doing one subtraction in most cases anyway, and so I decided to make the inclusive version use `checked_add` so it didn't have this lopsided overflow-checks-but-only-sometimes logic.
2 parents 409e7f6 + 08aa6c9 commit 4514fb9

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

library/core/src/iter/range.rs

+20
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,15 @@ impl<A: Step> Iterator for ops::Range<A> {
765765
}
766766
}
767767

768+
#[inline]
769+
fn count(self) -> usize {
770+
if self.start < self.end {
771+
Step::steps_between(&self.start, &self.end).expect("count overflowed usize")
772+
} else {
773+
0
774+
}
775+
}
776+
768777
#[inline]
769778
fn nth(&mut self, n: usize) -> Option<A> {
770779
self.spec_nth(n)
@@ -1162,6 +1171,17 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
11621171
}
11631172
}
11641173

1174+
#[inline]
1175+
fn count(self) -> usize {
1176+
if self.is_empty() {
1177+
return 0;
1178+
}
1179+
1180+
Step::steps_between(&self.start, &self.end)
1181+
.and_then(|steps| steps.checked_add(1))
1182+
.expect("count overflowed usize")
1183+
}
1184+
11651185
#[inline]
11661186
fn nth(&mut self, n: usize) -> Option<A> {
11671187
if self.is_empty() {

0 commit comments

Comments
 (0)