Skip to content

Commit 8741770

Browse files
committed
Update size_hint()s on std::iterator Iterators
Add size_hint() to a few Iterators that were missing it. Update a couple of existing size_hint()s to use checked_add() instead of saturating_add() for the upper bound.
1 parent c64f963 commit 8741770

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

src/libstd/iterator.rs

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ implementing the `Iterator` trait.
1818
*/
1919

2020
use cmp;
21-
use num::{Zero, One, Integer, Saturating};
21+
use num::{Zero, One, Integer, CheckedAdd, Saturating};
2222
use option::{Option, Some, None};
2323
use ops::{Add, Mul, Sub};
2424
use cmp::Ord;
@@ -817,7 +817,7 @@ impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for Chain<T, U> {
817817
let lower = a_lower.saturating_add(b_lower);
818818

819819
let upper = match (a_upper, b_upper) {
820-
(Some(x), Some(y)) => Some(x.saturating_add(y)),
820+
(Some(x), Some(y)) => x.checked_add(&y),
821821
_ => None
822822
};
823823

@@ -1094,22 +1094,34 @@ impl<A, T: Iterator<A>> Iterator<A> for Peekable<A, T> {
10941094
if self.peeked.is_some() { self.peeked.take() }
10951095
else { self.iter.next() }
10961096
}
1097+
1098+
#[inline]
1099+
fn size_hint(&self) -> (uint, Option<uint>) {
1100+
let (lo, hi) = self.iter.size_hint();
1101+
if self.peeked.is_some() {
1102+
let lo = lo.saturating_add(1);
1103+
let hi = match hi {
1104+
Some(x) => x.checked_add(&1),
1105+
None => None
1106+
};
1107+
(lo, hi)
1108+
} else {
1109+
(lo, hi)
1110+
}
1111+
}
10971112
}
10981113

10991114
impl<'self, A, T: Iterator<A>> Peekable<A, T> {
11001115
/// Return a reference to the next element of the iterator with out advancing it,
11011116
/// or None if the iterator is exhausted.
11021117
#[inline]
11031118
pub fn peek(&'self mut self) -> Option<&'self A> {
1119+
if self.peeked.is_none() {
1120+
self.peeked = self.iter.next();
1121+
}
11041122
match self.peeked {
11051123
Some(ref value) => Some(value),
1106-
None => {
1107-
self.peeked = self.iter.next();
1108-
match self.peeked {
1109-
Some(ref value) => Some(value),
1110-
None => None,
1111-
}
1112-
},
1124+
None => None,
11131125
}
11141126
}
11151127
}
@@ -1355,7 +1367,7 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
13551367
let (blo, bhi) = self.backiter.map_default((0, Some(0)), |it| it.size_hint());
13561368
let lo = flo.saturating_add(blo);
13571369
match (self.iter.size_hint(), fhi, bhi) {
1358-
((0, Some(0)), Some(a), Some(b)) => (lo, Some(a.saturating_add(b))),
1370+
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(&b)),
13591371
_ => (lo, None)
13601372
}
13611373
}
@@ -1461,6 +1473,12 @@ impl<'self, A, St> Iterator<A> for Unfoldr<'self, A, St> {
14611473
fn next(&mut self) -> Option<A> {
14621474
(self.f)(&mut self.state)
14631475
}
1476+
1477+
#[inline]
1478+
fn size_hint(&self) -> (uint, Option<uint>) {
1479+
// no possible known bounds at this point
1480+
(0, None)
1481+
}
14641482
}
14651483

14661484
/// An infinite iterator starting at `start` and advancing by `step` with each
@@ -1504,6 +1522,9 @@ impl<A: Add<A, A> + Ord + Clone> Iterator<A> for Range<A> {
15041522
None
15051523
}
15061524
}
1525+
1526+
// FIXME: #8606 Implement size_hint() on Range
1527+
// Blocked on #8605 Need numeric trait for converting to `Option<uint>`
15071528
}
15081529

15091530
impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for Range<A> {

0 commit comments

Comments
 (0)