Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 84125b2

Browse files
committedJun 21, 2022
Specialize len for ExactSizeIterator with unmistakable size_hint
1 parent dc80ca7 commit 84125b2

File tree

15 files changed

+286
-89
lines changed

15 files changed

+286
-89
lines changed
 

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

+22-2
Original file line numberDiff line numberDiff line change
@@ -1342,6 +1342,10 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
13421342

13431343
#[stable(feature = "rust1", since = "1.0.0")]
13441344
impl<T> ExactSizeIterator for Iter<'_, T> {
1345+
fn len(&self) -> usize {
1346+
self.iter.len()
1347+
}
1348+
13451349
fn is_empty(&self) -> bool {
13461350
self.iter.is_empty()
13471351
}
@@ -1395,6 +1399,10 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
13951399

13961400
#[stable(feature = "rust1", since = "1.0.0")]
13971401
impl<T> ExactSizeIterator for IntoIter<T> {
1402+
fn len(&self) -> usize {
1403+
self.iter.len()
1404+
}
1405+
13981406
fn is_empty(&self) -> bool {
13991407
self.iter.is_empty()
14001408
}
@@ -1452,7 +1460,11 @@ impl<T: Ord> Iterator for IntoIterSorted<T> {
14521460
}
14531461

14541462
#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
1455-
impl<T: Ord> ExactSizeIterator for IntoIterSorted<T> {}
1463+
impl<T: Ord> ExactSizeIterator for IntoIterSorted<T> {
1464+
fn len(&self) -> usize {
1465+
self.inner.len()
1466+
}
1467+
}
14561468

14571469
#[unstable(feature = "binary_heap_into_iter_sorted", issue = "59278")]
14581470
impl<T: Ord> FusedIterator for IntoIterSorted<T> {}
@@ -1497,6 +1509,10 @@ impl<T> DoubleEndedIterator for Drain<'_, T> {
14971509

14981510
#[stable(feature = "drain", since = "1.6.0")]
14991511
impl<T> ExactSizeIterator for Drain<'_, T> {
1512+
fn len(&self) -> usize {
1513+
self.iter.len()
1514+
}
1515+
15001516
fn is_empty(&self) -> bool {
15011517
self.iter.is_empty()
15021518
}
@@ -1554,7 +1570,11 @@ impl<T: Ord> Iterator for DrainSorted<'_, T> {
15541570
}
15551571

15561572
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
1557-
impl<T: Ord> ExactSizeIterator for DrainSorted<'_, T> {}
1573+
impl<T: Ord> ExactSizeIterator for DrainSorted<'_, T> {
1574+
fn len(&self) -> usize {
1575+
self.inner.len()
1576+
}
1577+
}
15581578

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

‎library/alloc/src/collections/linked_list.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,12 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
10701070
}
10711071

10721072
#[stable(feature = "rust1", since = "1.0.0")]
1073-
impl<T> ExactSizeIterator for Iter<'_, T> {}
1073+
impl<T> ExactSizeIterator for Iter<'_, T> {
1074+
#[inline]
1075+
fn len(&self) -> usize {
1076+
self.len
1077+
}
1078+
}
10741079

10751080
#[stable(feature = "fused", since = "1.26.0")]
10761081
impl<T> FusedIterator for Iter<'_, T> {}
@@ -1124,7 +1129,11 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
11241129
}
11251130

11261131
#[stable(feature = "rust1", since = "1.0.0")]
1127-
impl<T> ExactSizeIterator for IterMut<'_, T> {}
1132+
impl<T> ExactSizeIterator for IterMut<'_, T> {
1133+
fn len(&self) -> usize {
1134+
self.len
1135+
}
1136+
}
11281137

11291138
#[stable(feature = "fused", since = "1.26.0")]
11301139
impl<T> FusedIterator for IterMut<'_, T> {}
@@ -1803,7 +1812,11 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
18031812
}
18041813

18051814
#[stable(feature = "rust1", since = "1.0.0")]
1806-
impl<T> ExactSizeIterator for IntoIter<T> {}
1815+
impl<T> ExactSizeIterator for IntoIter<T> {
1816+
fn len(&self) -> usize {
1817+
self.list.len
1818+
}
1819+
}
18071820

18081821
#[stable(feature = "fused", since = "1.26.0")]
18091822
impl<T> FusedIterator for IntoIter<T> {}

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,14 @@ impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
136136
}
137137

138138
#[stable(feature = "drain", since = "1.6.0")]
139-
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {}
139+
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
140+
#[inline]
141+
fn len(&self) -> usize {
142+
let n = self.iter.len();
143+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
144+
n
145+
}
146+
}
140147

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

‎library/alloc/src/collections/vec_deque/into_iter.rs

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
6060

6161
#[stable(feature = "rust1", since = "1.0.0")]
6262
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
63+
#[inline]
64+
fn len(&self) -> usize {
65+
self.inner.len()
66+
}
67+
6368
fn is_empty(&self) -> bool {
6469
self.inner.is_empty()
6570
}

‎library/alloc/src/collections/vec_deque/iter.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
6767

6868
#[inline]
6969
fn size_hint(&self) -> (usize, Option<usize>) {
70-
let len = count(self.tail, self.head, self.ring.len());
70+
let len = self.len();
7171
(len, Some(len))
7272
}
7373

@@ -113,7 +113,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
113113
}
114114

115115
fn nth(&mut self, n: usize) -> Option<Self::Item> {
116-
if n >= count(self.tail, self.head, self.ring.len()) {
116+
if n >= self.len() {
117117
self.tail = self.head;
118118
None
119119
} else {
@@ -197,6 +197,11 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
197197

198198
#[stable(feature = "rust1", since = "1.0.0")]
199199
impl<T> ExactSizeIterator for Iter<'_, T> {
200+
#[inline]
201+
fn len(&self) -> usize {
202+
count(self.tail, self.head, self.ring.len())
203+
}
204+
200205
fn is_empty(&self) -> bool {
201206
self.head == self.tail
202207
}

‎library/alloc/src/collections/vec_deque/iter_mut.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl<'a, T> Iterator for IterMut<'a, T> {
6868

6969
#[inline]
7070
fn size_hint(&self) -> (usize, Option<usize>) {
71-
let len = count(self.tail, self.head, self.ring.len());
71+
let len = self.len();
7272
(len, Some(len))
7373
}
7474

@@ -85,7 +85,7 @@ impl<'a, T> Iterator for IterMut<'a, T> {
8585
}
8686

8787
fn nth(&mut self, n: usize) -> Option<Self::Item> {
88-
if n >= count(self.tail, self.head, self.ring.len()) {
88+
if n >= self.len() {
8989
self.tail = self.head;
9090
None
9191
} else {
@@ -140,6 +140,11 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
140140

141141
#[stable(feature = "rust1", since = "1.0.0")]
142142
impl<T> ExactSizeIterator for IterMut<'_, T> {
143+
#[inline]
144+
fn len(&self) -> usize {
145+
count(self.tail, self.head, self.ring.len())
146+
}
147+
143148
fn is_empty(&self) -> bool {
144149
self.head == self.tail
145150
}

‎library/alloc/src/vec/drain.rs

+4
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> {
172172

173173
#[stable(feature = "drain", since = "1.6.0")]
174174
impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {
175+
fn len(&self) -> usize {
176+
self.iter.len()
177+
}
178+
175179
fn is_empty(&self) -> bool {
176180
self.iter.is_empty()
177181
}

‎library/alloc/src/vec/into_iter.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
166166

167167
#[inline]
168168
fn size_hint(&self) -> (usize, Option<usize>) {
169-
let exact = if mem::size_of::<T>() == 0 {
170-
self.end.addr().wrapping_sub(self.ptr.addr())
171-
} else {
172-
unsafe { self.end.sub_ptr(self.ptr) }
173-
};
169+
let exact = self.len();
174170
(exact, Some(exact))
175171
}
176172

@@ -265,6 +261,15 @@ impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
265261

266262
#[stable(feature = "rust1", since = "1.0.0")]
267263
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
264+
#[inline]
265+
fn len(&self) -> usize {
266+
if mem::size_of::<T>() == 0 {
267+
self.end.addr().wrapping_sub(self.ptr.addr())
268+
} else {
269+
unsafe { self.end.sub_ptr(self.ptr) }
270+
}
271+
}
272+
268273
fn is_empty(&self) -> bool {
269274
self.ptr == self.end
270275
}

‎library/alloc/src/vec/splice.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@ 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+
let n = self.drain.len();
54+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
55+
n
56+
}
57+
}
5258

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

‎library/core/src/ascii.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ impl DoubleEndedIterator for EscapeDefault {
129129
}
130130
}
131131
#[stable(feature = "rust1", since = "1.0.0")]
132-
impl ExactSizeIterator for EscapeDefault {}
132+
impl ExactSizeIterator for EscapeDefault {
133+
fn len(&self) -> usize {
134+
self.range.len()
135+
}
136+
}
133137
#[stable(feature = "fused", since = "1.26.0")]
134138
impl FusedIterator for EscapeDefault {}
135139

‎library/core/src/char/mod.rs

+30-6
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,13 @@ impl Iterator for EscapeDebug {
386386
}
387387

388388
#[stable(feature = "char_escape_debug", since = "1.20.0")]
389-
impl ExactSizeIterator for EscapeDebug {}
389+
impl ExactSizeIterator for EscapeDebug {
390+
fn len(&self) -> usize {
391+
let n = self.0.len();
392+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
393+
n
394+
}
395+
}
390396

391397
#[stable(feature = "fused", since = "1.26.0")]
392398
impl FusedIterator for EscapeDebug {}
@@ -430,7 +436,13 @@ impl DoubleEndedIterator for ToLowercase {
430436
impl FusedIterator for ToLowercase {}
431437

432438
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
433-
impl ExactSizeIterator for ToLowercase {}
439+
impl ExactSizeIterator for ToLowercase {
440+
fn len(&self) -> usize {
441+
let n = self.0.len();
442+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
443+
n
444+
}
445+
}
434446

435447
/// Returns an iterator that yields the uppercase equivalent of a `char`.
436448
///
@@ -464,7 +476,13 @@ impl DoubleEndedIterator for ToUppercase {
464476
impl FusedIterator for ToUppercase {}
465477

466478
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
467-
impl ExactSizeIterator for ToUppercase {}
479+
impl ExactSizeIterator for ToUppercase {
480+
fn len(&self) -> usize {
481+
let n = self.0.len();
482+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
483+
n
484+
}
485+
}
468486

469487
#[derive(Debug, Clone)]
470488
enum CaseMappingIter {
@@ -509,13 +527,19 @@ impl Iterator for CaseMappingIter {
509527
}
510528

511529
fn size_hint(&self) -> (usize, Option<usize>) {
512-
let size = match self {
530+
let size = self.len();
531+
(size, Some(size))
532+
}
533+
}
534+
535+
impl CaseMappingIter {
536+
fn len(&self) -> usize {
537+
match self {
513538
CaseMappingIter::Three(..) => 3,
514539
CaseMappingIter::Two(..) => 2,
515540
CaseMappingIter::One(_) => 1,
516541
CaseMappingIter::Zero => 0,
517-
};
518-
(size, Some(size))
542+
}
519543
}
520544
}
521545

‎library/core/src/iter/traits/exact_size.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ pub trait ExactSizeIterator: Iterator {
102102
fn len(&self) -> usize {
103103
let (lower, upper) = self.size_hint();
104104
// Note: This assertion is overly defensive, but it checks the invariant
105-
// guaranteed by the trait. If this trait were rust-internal,
106-
// we could use debug_assert!; assert_eq! will check all Rust user
107-
// implementations too.
105+
// guaranteed by the trait in all Rust user implementations too.
106+
// If this trait were rust-internal, we could use debug_assert!, but
107+
// any implementation for which it matters can override `len`.
108108
assert_eq!(upper, Some(lower));
109109
lower
110110
}

‎library/core/src/option.rs

+36-8
Original file line numberDiff line numberDiff line change
@@ -2049,10 +2049,8 @@ impl<A> Iterator for Item<A> {
20492049

20502050
#[inline]
20512051
fn size_hint(&self) -> (usize, Option<usize>) {
2052-
match self.opt {
2053-
Some(_) => (1, Some(1)),
2054-
None => (0, Some(0)),
2055-
}
2052+
let exact = self.len();
2053+
(exact, Some(exact))
20562054
}
20572055
}
20582056

@@ -2063,7 +2061,16 @@ impl<A> DoubleEndedIterator for Item<A> {
20632061
}
20642062
}
20652063

2066-
impl<A> ExactSizeIterator for Item<A> {}
2064+
impl<A> ExactSizeIterator for Item<A> {
2065+
#[inline]
2066+
fn len(&self) -> usize {
2067+
match self.opt {
2068+
Some(_) => 1,
2069+
None => 0,
2070+
}
2071+
}
2072+
}
2073+
20672074
impl<A> FusedIterator for Item<A> {}
20682075
unsafe impl<A> TrustedLen for Item<A> {}
20692076

@@ -2101,7 +2108,14 @@ impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
21012108
}
21022109

21032110
#[stable(feature = "rust1", since = "1.0.0")]
2104-
impl<A> ExactSizeIterator for Iter<'_, A> {}
2111+
impl<A> ExactSizeIterator for Iter<'_, A> {
2112+
#[inline]
2113+
fn len(&self) -> usize {
2114+
let n = self.inner.len();
2115+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
2116+
n
2117+
}
2118+
}
21052119

21062120
#[stable(feature = "fused", since = "1.26.0")]
21072121
impl<A> FusedIterator for Iter<'_, A> {}
@@ -2151,7 +2165,14 @@ impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
21512165
}
21522166

21532167
#[stable(feature = "rust1", since = "1.0.0")]
2154-
impl<A> ExactSizeIterator for IterMut<'_, A> {}
2168+
impl<A> ExactSizeIterator for IterMut<'_, A> {
2169+
#[inline]
2170+
fn len(&self) -> usize {
2171+
let n = self.inner.len();
2172+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
2173+
n
2174+
}
2175+
}
21552176

21562177
#[stable(feature = "fused", since = "1.26.0")]
21572178
impl<A> FusedIterator for IterMut<'_, A> {}
@@ -2192,7 +2213,14 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
21922213
}
21932214

21942215
#[stable(feature = "rust1", since = "1.0.0")]
2195-
impl<A> ExactSizeIterator for IntoIter<A> {}
2216+
impl<A> ExactSizeIterator for IntoIter<A> {
2217+
#[inline]
2218+
fn len(&self) -> usize {
2219+
let n = self.inner.len();
2220+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
2221+
n
2222+
}
2223+
}
21962224

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

‎library/core/src/result.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -1919,7 +1919,7 @@ impl<'a, T> Iterator for Iter<'a, T> {
19191919
}
19201920
#[inline]
19211921
fn size_hint(&self) -> (usize, Option<usize>) {
1922-
let n = if self.inner.is_some() { 1 } else { 0 };
1922+
let n = self.len();
19231923
(n, Some(n))
19241924
}
19251925
}
@@ -1933,7 +1933,12 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
19331933
}
19341934

19351935
#[stable(feature = "rust1", since = "1.0.0")]
1936-
impl<T> ExactSizeIterator for Iter<'_, T> {}
1936+
impl<T> ExactSizeIterator for Iter<'_, T> {
1937+
#[inline]
1938+
fn len(&self) -> usize {
1939+
if self.inner.is_some() { 1 } else { 0 }
1940+
}
1941+
}
19371942

19381943
#[stable(feature = "fused", since = "1.26.0")]
19391944
impl<T> FusedIterator for Iter<'_, T> {}
@@ -1968,7 +1973,7 @@ impl<'a, T> Iterator for IterMut<'a, T> {
19681973
}
19691974
#[inline]
19701975
fn size_hint(&self) -> (usize, Option<usize>) {
1971-
let n = if self.inner.is_some() { 1 } else { 0 };
1976+
let n = self.len();
19721977
(n, Some(n))
19731978
}
19741979
}
@@ -1982,7 +1987,12 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
19821987
}
19831988

19841989
#[stable(feature = "rust1", since = "1.0.0")]
1985-
impl<T> ExactSizeIterator for IterMut<'_, T> {}
1990+
impl<T> ExactSizeIterator for IterMut<'_, T> {
1991+
#[inline]
1992+
fn len(&self) -> usize {
1993+
if self.inner.is_some() { 1 } else { 0 }
1994+
}
1995+
}
19861996

19871997
#[stable(feature = "fused", since = "1.26.0")]
19881998
impl<T> FusedIterator for IterMut<'_, T> {}
@@ -2014,7 +2024,7 @@ impl<T> Iterator for IntoIter<T> {
20142024
}
20152025
#[inline]
20162026
fn size_hint(&self) -> (usize, Option<usize>) {
2017-
let n = if self.inner.is_some() { 1 } else { 0 };
2027+
let n = self.len();
20182028
(n, Some(n))
20192029
}
20202030
}
@@ -2028,7 +2038,12 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
20282038
}
20292039

20302040
#[stable(feature = "rust1", since = "1.0.0")]
2031-
impl<T> ExactSizeIterator for IntoIter<T> {}
2041+
impl<T> ExactSizeIterator for IntoIter<T> {
2042+
#[inline]
2043+
fn len(&self) -> usize {
2044+
if self.inner.is_some() { 1 } else { 0 }
2045+
}
2046+
}
20322047

20332048
#[stable(feature = "fused", since = "1.26.0")]
20342049
impl<T> FusedIterator for IntoIter<T> {}

‎library/core/src/slice/iter.rs

+105-49
Original file line numberDiff line numberDiff line change
@@ -1334,12 +1334,8 @@ impl<'a, T> Iterator for Windows<'a, T> {
13341334

13351335
#[inline]
13361336
fn size_hint(&self) -> (usize, Option<usize>) {
1337-
if self.size.get() > self.v.len() {
1338-
(0, Some(0))
1339-
} else {
1340-
let size = self.v.len() - self.size.get() + 1;
1341-
(size, Some(size))
1342-
}
1337+
let size = self.len();
1338+
(size, Some(size))
13431339
}
13441340

13451341
#[inline]
@@ -1407,7 +1403,12 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
14071403
}
14081404

14091405
#[stable(feature = "rust1", since = "1.0.0")]
1410-
impl<T> ExactSizeIterator for Windows<'_, T> {}
1406+
impl<T> ExactSizeIterator for Windows<'_, T> {
1407+
#[inline]
1408+
fn len(&self) -> usize {
1409+
if self.size.get() > self.v.len() { 0 } else { self.v.len() - self.size.get() + 1 }
1410+
}
1411+
}
14111412

14121413
#[unstable(feature = "trusted_len", issue = "37572")]
14131414
unsafe impl<T> TrustedLen for Windows<'_, T> {}
@@ -1483,14 +1484,8 @@ impl<'a, T> Iterator for Chunks<'a, T> {
14831484

14841485
#[inline]
14851486
fn size_hint(&self) -> (usize, Option<usize>) {
1486-
if self.v.is_empty() {
1487-
(0, Some(0))
1488-
} else {
1489-
let n = self.v.len() / self.chunk_size;
1490-
let rem = self.v.len() % self.chunk_size;
1491-
let n = if rem > 0 { n + 1 } else { n };
1492-
(n, Some(n))
1493-
}
1487+
let n = self.len();
1488+
(n, Some(n))
14941489
}
14951490

14961491
#[inline]
@@ -1590,7 +1585,18 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
15901585
}
15911586

15921587
#[stable(feature = "rust1", since = "1.0.0")]
1593-
impl<T> ExactSizeIterator for Chunks<'_, T> {}
1588+
impl<T> ExactSizeIterator for Chunks<'_, T> {
1589+
#[inline]
1590+
fn len(&self) -> usize {
1591+
if self.v.is_empty() {
1592+
0
1593+
} else {
1594+
let n = self.v.len() / self.chunk_size;
1595+
let rem = self.v.len() % self.chunk_size;
1596+
if rem > 0 { n + 1 } else { n }
1597+
}
1598+
}
1599+
}
15941600

15951601
#[unstable(feature = "trusted_len", issue = "37572")]
15961602
unsafe impl<T> TrustedLen for Chunks<'_, T> {}
@@ -1659,14 +1665,8 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
16591665

16601666
#[inline]
16611667
fn size_hint(&self) -> (usize, Option<usize>) {
1662-
if self.v.is_empty() {
1663-
(0, Some(0))
1664-
} else {
1665-
let n = self.v.len() / self.chunk_size;
1666-
let rem = self.v.len() % self.chunk_size;
1667-
let n = if rem > 0 { n + 1 } else { n };
1668-
(n, Some(n))
1669-
}
1668+
let n = self.len();
1669+
(n, Some(n))
16701670
}
16711671

16721672
#[inline]
@@ -1757,7 +1757,18 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
17571757
}
17581758

17591759
#[stable(feature = "rust1", since = "1.0.0")]
1760-
impl<T> ExactSizeIterator for ChunksMut<'_, T> {}
1760+
impl<T> ExactSizeIterator for ChunksMut<'_, T> {
1761+
#[inline]
1762+
fn len(&self) -> usize {
1763+
if self.v.is_empty() {
1764+
0
1765+
} else {
1766+
let n = self.v.len() / self.chunk_size;
1767+
let rem = self.v.len() % self.chunk_size;
1768+
if rem > 0 { n + 1 } else { n }
1769+
}
1770+
}
1771+
}
17611772

17621773
#[unstable(feature = "trusted_len", issue = "37572")]
17631774
unsafe impl<T> TrustedLen for ChunksMut<'_, T> {}
@@ -1848,7 +1859,7 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
18481859

18491860
#[inline]
18501861
fn size_hint(&self) -> (usize, Option<usize>) {
1851-
let n = self.v.len() / self.chunk_size;
1862+
let n = self.len();
18521863
(n, Some(n))
18531864
}
18541865

@@ -1913,6 +1924,11 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
19131924

19141925
#[stable(feature = "chunks_exact", since = "1.31.0")]
19151926
impl<T> ExactSizeIterator for ChunksExact<'_, T> {
1927+
#[inline]
1928+
fn len(&self) -> usize {
1929+
self.v.len() / self.chunk_size
1930+
}
1931+
19161932
fn is_empty(&self) -> bool {
19171933
self.v.is_empty()
19181934
}
@@ -2000,7 +2016,7 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
20002016

20012017
#[inline]
20022018
fn size_hint(&self) -> (usize, Option<usize>) {
2003-
let n = self.v.len() / self.chunk_size;
2019+
let n = self.len();
20042020
(n, Some(n))
20052021
}
20062022

@@ -2069,6 +2085,11 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
20692085

20702086
#[stable(feature = "chunks_exact", since = "1.31.0")]
20712087
impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
2088+
#[inline]
2089+
fn len(&self) -> usize {
2090+
self.v.len() / self.chunk_size
2091+
}
2092+
20722093
fn is_empty(&self) -> bool {
20732094
self.v.is_empty()
20742095
}
@@ -2203,8 +2224,9 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
22032224

22042225
#[unstable(feature = "array_windows", issue = "75027")]
22052226
impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
2206-
fn is_empty(&self) -> bool {
2207-
self.num == 0
2227+
#[inline]
2228+
fn len(&self) -> usize {
2229+
self.num
22082230
}
22092231
}
22102232

@@ -2313,6 +2335,13 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunks<'a, T, N> {
23132335

23142336
#[unstable(feature = "array_chunks", issue = "74985")]
23152337
impl<T, const N: usize> ExactSizeIterator for ArrayChunks<'_, T, N> {
2338+
#[inline]
2339+
fn len(&self) -> usize {
2340+
let n = self.iter.len();
2341+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
2342+
n
2343+
}
2344+
23162345
fn is_empty(&self) -> bool {
23172346
self.iter.is_empty()
23182347
}
@@ -2431,6 +2460,13 @@ impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunksMut<'a, T, N> {
24312460

24322461
#[unstable(feature = "array_chunks", issue = "74985")]
24332462
impl<T, const N: usize> ExactSizeIterator for ArrayChunksMut<'_, T, N> {
2463+
#[inline]
2464+
fn len(&self) -> usize {
2465+
let n = self.iter.len();
2466+
debug_assert_eq!(self.size_hint(), (n, Some(n)));
2467+
n
2468+
}
2469+
24342470
fn is_empty(&self) -> bool {
24352471
self.iter.is_empty()
24362472
}
@@ -2516,14 +2552,8 @@ impl<'a, T> Iterator for RChunks<'a, T> {
25162552

25172553
#[inline]
25182554
fn size_hint(&self) -> (usize, Option<usize>) {
2519-
if self.v.is_empty() {
2520-
(0, Some(0))
2521-
} else {
2522-
let n = self.v.len() / self.chunk_size;
2523-
let rem = self.v.len() % self.chunk_size;
2524-
let n = if rem > 0 { n + 1 } else { n };
2525-
(n, Some(n))
2526-
}
2555+
let n = self.len();
2556+
(n, Some(n))
25272557
}
25282558

25292559
#[inline]
@@ -2607,7 +2637,18 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
26072637
}
26082638

26092639
#[stable(feature = "rchunks", since = "1.31.0")]
2610-
impl<T> ExactSizeIterator for RChunks<'_, T> {}
2640+
impl<T> ExactSizeIterator for RChunks<'_, T> {
2641+
#[inline]
2642+
fn len(&self) -> usize {
2643+
if self.v.is_empty() {
2644+
0
2645+
} else {
2646+
let n = self.v.len() / self.chunk_size;
2647+
let rem = self.v.len() % self.chunk_size;
2648+
if rem > 0 { n + 1 } else { n }
2649+
}
2650+
}
2651+
}
26112652

26122653
#[unstable(feature = "trusted_len", issue = "37572")]
26132654
unsafe impl<T> TrustedLen for RChunks<'_, T> {}
@@ -2682,14 +2723,8 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
26822723

26832724
#[inline]
26842725
fn size_hint(&self) -> (usize, Option<usize>) {
2685-
if self.v.is_empty() {
2686-
(0, Some(0))
2687-
} else {
2688-
let n = self.v.len() / self.chunk_size;
2689-
let rem = self.v.len() % self.chunk_size;
2690-
let n = if rem > 0 { n + 1 } else { n };
2691-
(n, Some(n))
2692-
}
2726+
let n = self.len();
2727+
(n, Some(n))
26932728
}
26942729

26952730
#[inline]
@@ -2778,7 +2813,18 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
27782813
}
27792814

27802815
#[stable(feature = "rchunks", since = "1.31.0")]
2781-
impl<T> ExactSizeIterator for RChunksMut<'_, T> {}
2816+
impl<T> ExactSizeIterator for RChunksMut<'_, T> {
2817+
#[inline]
2818+
fn len(&self) -> usize {
2819+
if self.v.is_empty() {
2820+
0
2821+
} else {
2822+
let n = self.v.len() / self.chunk_size;
2823+
let rem = self.v.len() % self.chunk_size;
2824+
if rem > 0 { n + 1 } else { n }
2825+
}
2826+
}
2827+
}
27822828

27832829
#[unstable(feature = "trusted_len", issue = "37572")]
27842830
unsafe impl<T> TrustedLen for RChunksMut<'_, T> {}
@@ -2868,7 +2914,7 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
28682914

28692915
#[inline]
28702916
fn size_hint(&self) -> (usize, Option<usize>) {
2871-
let n = self.v.len() / self.chunk_size;
2917+
let n = self.len();
28722918
(n, Some(n))
28732919
}
28742920

@@ -2938,6 +2984,11 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
29382984

29392985
#[stable(feature = "rchunks", since = "1.31.0")]
29402986
impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
2987+
#[inline]
2988+
fn len(&self) -> usize {
2989+
self.v.len() / self.chunk_size
2990+
}
2991+
29412992
fn is_empty(&self) -> bool {
29422993
self.v.is_empty()
29432994
}
@@ -3025,7 +3076,7 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
30253076

30263077
#[inline]
30273078
fn size_hint(&self) -> (usize, Option<usize>) {
3028-
let n = self.v.len() / self.chunk_size;
3079+
let n = self.len();
30293080
(n, Some(n))
30303081
}
30313082

@@ -3098,6 +3149,11 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
30983149

30993150
#[stable(feature = "rchunks", since = "1.31.0")]
31003151
impl<T> ExactSizeIterator for RChunksExactMut<'_, T> {
3152+
#[inline]
3153+
fn len(&self) -> usize {
3154+
self.v.len() / self.chunk_size
3155+
}
3156+
31013157
fn is_empty(&self) -> bool {
31023158
self.v.is_empty()
31033159
}

0 commit comments

Comments
 (0)
Please sign in to comment.