From 8741770471d08c78780fd6c22c18c0cf28fcf074 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Sun, 18 Aug 2013 21:47:43 -0700 Subject: [PATCH] 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. --- src/libstd/iterator.rs | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 1d32c5df14ed..7425da973688 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -18,7 +18,7 @@ implementing the `Iterator` trait. */ use cmp; -use num::{Zero, One, Integer, Saturating}; +use num::{Zero, One, Integer, CheckedAdd, Saturating}; use option::{Option, Some, None}; use ops::{Add, Mul, Sub}; use cmp::Ord; @@ -817,7 +817,7 @@ impl, U: Iterator> Iterator for Chain { let lower = a_lower.saturating_add(b_lower); let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => Some(x.saturating_add(y)), + (Some(x), Some(y)) => x.checked_add(&y), _ => None }; @@ -1094,6 +1094,21 @@ impl> Iterator for Peekable { if self.peeked.is_some() { self.peeked.take() } else { self.iter.next() } } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let (lo, hi) = self.iter.size_hint(); + if self.peeked.is_some() { + let lo = lo.saturating_add(1); + let hi = match hi { + Some(x) => x.checked_add(&1), + None => None + }; + (lo, hi) + } else { + (lo, hi) + } + } } impl<'self, A, T: Iterator> Peekable { @@ -1101,15 +1116,12 @@ impl<'self, A, T: Iterator> Peekable { /// or None if the iterator is exhausted. #[inline] pub fn peek(&'self mut self) -> Option<&'self A> { + if self.peeked.is_none() { + self.peeked = self.iter.next(); + } match self.peeked { Some(ref value) => Some(value), - None => { - self.peeked = self.iter.next(); - match self.peeked { - Some(ref value) => Some(value), - None => None, - } - }, + None => None, } } } @@ -1355,7 +1367,7 @@ impl<'self, A, T: Iterator, B, U: Iterator> Iterator for let (blo, bhi) = self.backiter.map_default((0, Some(0)), |it| it.size_hint()); let lo = flo.saturating_add(blo); match (self.iter.size_hint(), fhi, bhi) { - ((0, Some(0)), Some(a), Some(b)) => (lo, Some(a.saturating_add(b))), + ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(&b)), _ => (lo, None) } } @@ -1461,6 +1473,12 @@ impl<'self, A, St> Iterator for Unfoldr<'self, A, St> { fn next(&mut self) -> Option { (self.f)(&mut self.state) } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + // no possible known bounds at this point + (0, None) + } } /// An infinite iterator starting at `start` and advancing by `step` with each @@ -1504,6 +1522,9 @@ impl + Ord + Clone> Iterator for Range { None } } + + // FIXME: #8606 Implement size_hint() on Range + // Blocked on #8605 Need numeric trait for converting to `Option` } impl + Integer + Ord + Clone> DoubleEndedIterator for Range {