diff options
| author | root <root@localhost> | 2014-08-24 15:04:28 +0200 |
|---|---|---|
| committer | root <root@localhost> | 2014-08-24 15:11:23 +0200 |
| commit | d363770851650d9e137d628de2efeb90b3154bb0 (patch) | |
| tree | 5c3b7863d8a28124475bfa0a486cd6567431e7a1 | |
| parent | 262d5a4686c80675fe5bfcb79b26b341b9a0bf7a (diff) | |
| download | rust-d363770851650d9e137d628de2efeb90b3154bb0.tar.gz rust-d363770851650d9e137d628de2efeb90b3154bb0.zip | |
libcore: Simplify Enumerate, Zip::next_back
Use ExactSize::len() and defer to its decisions about overly defensive assertions. Remove the length double-check and simply put a failure case if the Zip finds an uneven end in .next_back(). Fixing this up since I think I wrote this, and it's been known to confuse rusties (PR#15886).
| -rw-r--r-- | src/libcore/iter.rs | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index b8ed8bdf923..b2bd8d46fb5 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -728,6 +728,10 @@ pub trait ExactSize<A> : DoubleEndedIterator<A> { /// Return the exact length of the iterator. fn len(&self) -> uint { let (lower, upper) = self.size_hint(); + // Note: This assertion is overly defensive, but it checks the invariant + // guaranteed by the trait. If this trait were rust-internal, + // we could use debug_assert!; assert_eq! will check all Rust user + // implementations too. assert_eq!(upper, Some(lower)); lower } @@ -1195,21 +1199,20 @@ impl<A, B, T: ExactSize<A>, U: ExactSize<B>> DoubleEndedIterator<(A, B)> for Zip<T, U> { #[inline] fn next_back(&mut self) -> Option<(A, B)> { - let (a_sz, a_upper) = self.a.size_hint(); - let (b_sz, b_upper) = self.b.size_hint(); - assert!(a_upper == Some(a_sz)); - assert!(b_upper == Some(b_sz)); - if a_sz < b_sz { - for _ in range(0, b_sz - a_sz) { self.b.next_back(); } - } else if a_sz > b_sz { - for _ in range(0, a_sz - b_sz) { self.a.next_back(); } - } - let (a_sz, _) = self.a.size_hint(); - let (b_sz, _) = self.b.size_hint(); - assert!(a_sz == b_sz); + let a_sz = self.a.len(); + let b_sz = self.b.len(); + if a_sz != b_sz { + // Adjust a, b to equal length + if a_sz > b_sz { + for _ in range(0, a_sz - b_sz) { self.a.next_back(); } + } else { + for _ in range(0, b_sz - a_sz) { self.b.next_back(); } + } + } match (self.a.next_back(), self.b.next_back()) { (Some(x), Some(y)) => Some((x, y)), - _ => None + (None, None) => None, + _ => unreachable!(), } } } @@ -1395,9 +1398,8 @@ impl<A, T: ExactSize<A>> DoubleEndedIterator<(uint, A)> for Enumerate<T> { fn next_back(&mut self) -> Option<(uint, A)> { match self.iter.next_back() { Some(a) => { - let (lower, upper) = self.iter.size_hint(); - assert!(upper == Some(lower)); - Some((self.count + lower, a)) + let len = self.iter.len(); + Some((self.count + len, a)) } _ => None } |
