Skip to content

Commit 200d71b

Browse files
author
Clar Fon
committed
Add Iterator::max_size_hint
1 parent 147311c commit 200d71b

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

Diff for: src/libcore/iter/adapters/flatten.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,19 @@ impl<I, U> Iterator for FlattenCompat<I, U>
226226
fn size_hint(&self) -> (usize, Option<usize>) {
227227
let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
228228
let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
229-
let lo = flo.saturating_add(blo);
230-
match (self.iter.size_hint(), fhi, bhi) {
231-
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
232-
_ => (lo, None)
233-
}
229+
let (mlo, mhi) = self.iter.size_hint();
230+
let max = U::max_size_hint();
231+
232+
let lo = flo.saturating_add(blo).saturating_add(mlo.saturating_mul(max.unwrap_or(0)));
233+
let hi = match (fhi, bhi, mhi, max) {
234+
(Some(f), Some(b), Some(0), None) => f.checked_add(b),
235+
(Some(f), Some(b), Some(m), Some(max)) => try {
236+
f.checked_add(b)?.checked_add(m.checked_mul(max)?)?
237+
},
238+
_ => None,
239+
};
240+
241+
(lo, hi)
234242
}
235243

236244
#[inline]

Diff for: src/libcore/iter/traits/iterator.rs

+9
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,15 @@ pub trait Iterator {
199199
#[stable(feature = "rust1", since = "1.0.0")]
200200
fn size_hint(&self) -> (usize, Option<usize>) { (0, None) }
201201

202+
/// An estimate of the maximum size of iterators of this type.
203+
///
204+
/// This is similar to [`size_hint`], with the exception that it applies to all
205+
/// iterators of this type. It can be used to optimize adapters like [`flatten`]
206+
/// and provide better size hints.
207+
#[inline]
208+
#[unstable(feature = "max_size_hint", issue = "0")]
209+
fn max_size_hint() -> Option<usize> where Self: Sized { None }
210+
202211
/// Consumes the iterator, counting the number of iterations and returning it.
203212
///
204213
/// This method will evaluate the iterator until its [`next`] returns

Diff for: src/libcore/option.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,8 @@ impl<'a, A> Iterator for Iter<'a, A> {
11721172
fn next(&mut self) -> Option<&'a A> { self.inner.next() }
11731173
#[inline]
11741174
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1175+
#[inline]
1176+
fn max_size_hint() -> Option<usize> { Some(1) }
11751177
}
11761178

11771179
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1218,6 +1220,8 @@ impl<'a, A> Iterator for IterMut<'a, A> {
12181220
fn next(&mut self) -> Option<&'a mut A> { self.inner.next() }
12191221
#[inline]
12201222
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1223+
#[inline]
1224+
fn max_size_hint() -> Option<usize> { Some(1) }
12211225
}
12221226

12231227
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1255,6 +1259,8 @@ impl<A> Iterator for IntoIter<A> {
12551259
fn next(&mut self) -> Option<A> { self.inner.next() }
12561260
#[inline]
12571261
fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
1262+
#[inline]
1263+
fn max_size_hint() -> Option<usize> { Some(1) }
12581264
}
12591265

12601266
#[stable(feature = "rust1", since = "1.0.0")]

Diff for: src/libcore/result.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,8 @@ impl<'a, T> Iterator for Iter<'a, T> {
10771077
let n = if self.inner.is_some() {1} else {0};
10781078
(n, Some(n))
10791079
}
1080+
#[inline]
1081+
fn max_size_hint() -> Option<usize> { Some(1) }
10801082
}
10811083

10821084
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1122,6 +1124,8 @@ impl<'a, T> Iterator for IterMut<'a, T> {
11221124
let n = if self.inner.is_some() {1} else {0};
11231125
(n, Some(n))
11241126
}
1127+
#[inline]
1128+
fn max_size_hint() -> Option<usize> { Some(1) }
11251129
}
11261130

11271131
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1165,6 +1169,8 @@ impl<T> Iterator for IntoIter<T> {
11651169
let n = if self.inner.is_some() {1} else {0};
11661170
(n, Some(n))
11671171
}
1172+
#[inline]
1173+
fn max_size_hint() -> Option<usize> { Some(1) }
11681174
}
11691175

11701176
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)