Skip to content

Commit ccdc19f

Browse files
Auto merge of #149384 - yotamofek:pr/library/default-exactsizeiter-impl, r=<try>
Don't delegate to default implementations of `ExactSizeIterator`
2 parents cf8a955 + a2e0e2e commit ccdc19f

File tree

12 files changed

+226
-71
lines changed

12 files changed

+226
-71
lines changed

library/alloc/src/collections/binary_heap/mod.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,7 +1720,12 @@ impl<T: Ord, A: Allocator> Iterator for IntoIterSorted<T, A> {
17201720
}
17211721

17221722
#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
1723-
impl<T: Ord, A: Allocator> ExactSizeIterator for IntoIterSorted<T, A> {}
1723+
impl<T: Ord, A: Allocator> ExactSizeIterator for IntoIterSorted<T, A> {
1724+
#[inline]
1725+
fn len(&self) -> usize {
1726+
self.inner.len()
1727+
}
1728+
}
17241729

17251730
#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
17261731
impl<T: Ord, A: Allocator> FusedIterator for IntoIterSorted<T, A> {}
@@ -1846,7 +1851,12 @@ impl<T: Ord, A: Allocator> Iterator for DrainSorted<'_, T, A> {
18461851
}
18471852

18481853
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
1849-
impl<T: Ord, A: Allocator> ExactSizeIterator for DrainSorted<'_, T, A> {}
1854+
impl<T: Ord, A: Allocator> ExactSizeIterator for DrainSorted<'_, T, A> {
1855+
#[inline]
1856+
fn len(&self) -> usize {
1857+
self.inner.len()
1858+
}
1859+
}
18501860

18511861
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
18521862
impl<T: Ord, A: Allocator> FusedIterator for DrainSorted<'_, T, A> {}

library/alloc/src/collections/linked_list.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,11 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
12441244
}
12451245

12461246
#[stable(feature = "rust1", since = "1.0.0")]
1247-
impl<T> ExactSizeIterator for Iter<'_, T> {}
1247+
impl<T> ExactSizeIterator for Iter<'_, T> {
1248+
fn len(&self) -> usize {
1249+
self.len
1250+
}
1251+
}
12481252

12491253
#[stable(feature = "fused", since = "1.26.0")]
12501254
impl<T> FusedIterator for Iter<'_, T> {}
@@ -1312,7 +1316,11 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
13121316
}
13131317

13141318
#[stable(feature = "rust1", since = "1.0.0")]
1315-
impl<T> ExactSizeIterator for IterMut<'_, T> {}
1319+
impl<T> ExactSizeIterator for IterMut<'_, T> {
1320+
fn len(&self) -> usize {
1321+
self.len
1322+
}
1323+
}
13161324

13171325
#[stable(feature = "fused", since = "1.26.0")]
13181326
impl<T> FusedIterator for IterMut<'_, T> {}
@@ -2023,7 +2031,11 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
20232031
}
20242032

20252033
#[stable(feature = "rust1", since = "1.0.0")]
2026-
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {}
2034+
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
2035+
fn len(&self) -> usize {
2036+
self.list.len
2037+
}
2038+
}
20272039

20282040
#[stable(feature = "fused", since = "1.26.0")]
20292041
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}

library/alloc/src/collections/vec_deque/drain.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,11 @@ impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
268268
}
269269

270270
#[stable(feature = "drain", since = "1.6.0")]
271-
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {}
271+
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
272+
fn len(&self) -> usize {
273+
self.remaining
274+
}
275+
}
272276

273277
#[stable(feature = "fused", since = "1.26.0")]
274278
impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}

library/alloc/src/vec/drain.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
241241

242242
#[stable(feature = "drain", since = "1.6.0")]
243243
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
244+
fn len(&self) -> usize {
245+
self.iter.len()
246+
}
247+
244248
fn is_empty(&self) -> bool {
245249
self.iter.is_empty()
246250
}

library/alloc/src/vec/splice.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ impl<I: Iterator, A: Allocator> DoubleEndedIterator for Splice<'_, I, A> {
4848
}
4949

5050
#[stable(feature = "vec_splice", since = "1.21.0")]
51-
impl<I: Iterator, A: Allocator> ExactSizeIterator for Splice<'_, I, A> {}
51+
impl<I: Iterator, A: Allocator> ExactSizeIterator for Splice<'_, I, A> {
52+
fn len(&self) -> usize {
53+
self.drain.len()
54+
}
55+
}
5256

5357
#[stable(feature = "vec_splice", since = "1.21.0")]
5458
impl<I: Iterator, A: Allocator> Drop for Splice<'_, I, A> {

library/core/src/iter/adapters/map_windows.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,30 @@ impl<I: Iterator, const N: usize> MapWindowsInner<I, N> {
9797
(lo, hi)
9898
} else {
9999
// If the first `N` items are not yet yielded by the inner iterator,
100-
// the first `N` elements should be counted as one window, so both bounds
101-
// should subtract `N - 1`.
100+
// the first `N` elements should be counted as one window, so `N - 1` should
101+
// subtracted from both bounds.
102102
(lo.saturating_sub(N - 1), hi.map(|hi| hi.saturating_sub(N - 1)))
103103
}
104104
}
105105
}
106106

107+
impl<I: ExactSizeIterator, const N: usize> MapWindowsInner<I, N> {
108+
fn len(&self) -> usize {
109+
let Some(ref iter) = self.iter else { return 0 };
110+
let n = iter.len();
111+
if self.buffer.is_some() {
112+
// If the first `N` items are already yielded by the inner iterator,
113+
// the length is then equal to the that of the inner iterator's.
114+
n
115+
} else {
116+
// If the first `N` items are not yet yielded by the inner iterator,
117+
// the first `N` elements should be counted as one window, so `N - 1` should
118+
// be subtracted from the length.
119+
n.saturating_sub(N - 1)
120+
}
121+
}
122+
}
123+
107124
impl<T, const N: usize> Buffer<T, N> {
108125
fn try_from_iter(iter: &mut impl Iterator<Item = T>) -> Option<Self> {
109126
let first_half = crate::array::iter_next_chunk(iter).ok()?;
@@ -269,6 +286,9 @@ where
269286
I: ExactSizeIterator,
270287
F: FnMut(&[I::Item; N]) -> R,
271288
{
289+
fn len(&self) -> usize {
290+
self.inner.len()
291+
}
272292
}
273293

274294
#[unstable(feature = "iter_map_windows", reason = "recently added", issue = "87155")]

library/core/src/iter/adapters/peekable.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,13 @@ where
168168
}
169169

170170
#[stable(feature = "rust1", since = "1.0.0")]
171-
impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
171+
impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {
172+
#[inline]
173+
fn len(&self) -> usize {
174+
let peek_len = usize::from(matches!(self.peeked, Some(Some(_))));
175+
self.iter.len().saturating_add(peek_len)
176+
}
177+
}
172178

173179
#[stable(feature = "fused", since = "1.26.0")]
174180
impl<I: FusedIterator> FusedIterator for Peekable<I> {}

library/core/src/iter/adapters/skip.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ where
185185
}
186186

187187
#[stable(feature = "rust1", since = "1.0.0")]
188-
impl<I> ExactSizeIterator for Skip<I> where I: ExactSizeIterator {}
188+
impl<I> ExactSizeIterator for Skip<I>
189+
where
190+
I: ExactSizeIterator,
191+
{
192+
fn len(&self) -> usize {
193+
self.iter.len().saturating_sub(self.n)
194+
}
195+
}
189196

190197
#[stable(feature = "double_ended_skip_iterator", since = "1.9.0")]
191198
impl<I> DoubleEndedIterator for Skip<I>

library/core/src/iter/adapters/take.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,14 @@ where
238238
}
239239

240240
#[stable(feature = "rust1", since = "1.0.0")]
241-
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
241+
impl<I> ExactSizeIterator for Take<I>
242+
where
243+
I: ExactSizeIterator,
244+
{
245+
fn len(&self) -> usize {
246+
cmp::min(self.n, self.iter.len())
247+
}
248+
}
242249

243250
#[stable(feature = "fused", since = "1.26.0")]
244251
impl<I> FusedIterator for Take<I> where I: FusedIterator {}

library/core/src/option.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ impl<T> Option<T> {
807807
}
808808

809809
#[inline]
810-
const fn len(&self) -> usize {
810+
pub(crate) const fn len(&self) -> usize {
811811
// Using the intrinsic avoids emitting a branch to get the 0 or 1.
812812
let discriminant: isize = crate::intrinsics::discriminant_value(self);
813813
discriminant as usize
@@ -2461,6 +2461,7 @@ impl<'a, A> Iterator for Iter<'a, A> {
24612461
fn next(&mut self) -> Option<&'a A> {
24622462
self.inner.next()
24632463
}
2464+
24642465
#[inline]
24652466
fn size_hint(&self) -> (usize, Option<usize>) {
24662467
self.inner.size_hint()
@@ -2476,7 +2477,11 @@ impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
24762477
}
24772478

24782479
#[stable(feature = "rust1", since = "1.0.0")]
2479-
impl<A> ExactSizeIterator for Iter<'_, A> {}
2480+
impl<A> ExactSizeIterator for Iter<'_, A> {
2481+
fn len(&self) -> usize {
2482+
self.inner.len()
2483+
}
2484+
}
24802485

24812486
#[stable(feature = "fused", since = "1.26.0")]
24822487
impl<A> FusedIterator for Iter<'_, A> {}
@@ -2511,6 +2516,7 @@ impl<'a, A> Iterator for IterMut<'a, A> {
25112516
fn next(&mut self) -> Option<&'a mut A> {
25122517
self.inner.next()
25132518
}
2519+
25142520
#[inline]
25152521
fn size_hint(&self) -> (usize, Option<usize>) {
25162522
self.inner.size_hint()
@@ -2526,7 +2532,11 @@ impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
25262532
}
25272533

25282534
#[stable(feature = "rust1", since = "1.0.0")]
2529-
impl<A> ExactSizeIterator for IterMut<'_, A> {}
2535+
impl<A> ExactSizeIterator for IterMut<'_, A> {
2536+
fn len(&self) -> usize {
2537+
self.inner.len()
2538+
}
2539+
}
25302540

25312541
#[stable(feature = "fused", since = "1.26.0")]
25322542
impl<A> FusedIterator for IterMut<'_, A> {}
@@ -2552,6 +2562,7 @@ impl<A> Iterator for IntoIter<A> {
25522562
fn next(&mut self) -> Option<A> {
25532563
self.inner.next()
25542564
}
2565+
25552566
#[inline]
25562567
fn size_hint(&self) -> (usize, Option<usize>) {
25572568
self.inner.size_hint()
@@ -2567,7 +2578,11 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
25672578
}
25682579

25692580
#[stable(feature = "rust1", since = "1.0.0")]
2570-
impl<A> ExactSizeIterator for IntoIter<A> {}
2581+
impl<A> ExactSizeIterator for IntoIter<A> {
2582+
fn len(&self) -> usize {
2583+
self.inner.len()
2584+
}
2585+
}
25712586

25722587
#[stable(feature = "fused", since = "1.26.0")]
25732588
impl<A> FusedIterator for IntoIter<A> {}

0 commit comments

Comments
 (0)