diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index c3bdfbb12d88d..80ae3076df37a 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -20,7 +20,7 @@ use cmp::{max, Eq, PartialEq}; use default::Default; use fmt::{self, Show}; use hash::{self, Hash, SipHasher}; -use iter::{self, Iterator, IteratorExt, FromIterator, Extend, Map}; +use iter::{self, Iterator, ExactSizeIterator, IteratorExt, FromIterator, Extend, Map}; use marker::Sized; use mem::{self, replace}; use num::{Int, UnsignedInt}; @@ -1384,7 +1384,11 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> { type Item = (&'a K, &'a V); #[inline] fn next(&mut self) -> Option<(&'a K, &'a V)> { self.inner.next() } - #[inline] fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable] +impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } } #[stable] @@ -1392,7 +1396,11 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); #[inline] fn next(&mut self) -> Option<(&'a K, &'a mut V)> { self.inner.next() } - #[inline] fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable] +impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } } #[stable] @@ -1400,7 +1408,11 @@ impl Iterator for IntoIter { type Item = (K, V); #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } - #[inline] fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable] +impl ExactSizeIterator for IntoIter { + #[inline] fn len(&self) -> usize { self.inner.len() } } #[stable] @@ -1408,7 +1420,11 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { type Item = &'a K; #[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() } - #[inline] fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable] +impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } } #[stable] @@ -1416,21 +1432,23 @@ impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; #[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() } - #[inline] fn size_hint(&self) -> (uint, Option) { self.inner.size_hint() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable] +impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } } #[stable] -impl<'a, K: 'a, V: 'a> Iterator for Drain<'a, K, V> { +impl<'a, K, V> Iterator for Drain<'a, K, V> { type Item = (K, V); - #[inline] - fn next(&mut self) -> Option<(K, V)> { - self.inner.next() - } - #[inline] - fn size_hint(&self) -> (uint, Option) { - self.inner.size_hint() - } + #[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() } + #[inline] fn size_hint(&self) -> (usize, Option) { self.inner.size_hint() } +} +#[stable] +impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { + #[inline] fn len(&self) -> usize { self.inner.len() } } #[unstable = "matches collection reform v2 specification, waiting for dust to settle"] @@ -2135,6 +2153,19 @@ mod test_map { assert_eq!(iter.size_hint(), (3, Some(3))); } + #[test] + fn test_iter_len() { + let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let map: HashMap = xs.iter().map(|&x| x).collect(); + + let mut iter = map.iter(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); + } + #[test] fn test_mut_size_hint() { let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; @@ -2148,6 +2179,19 @@ mod test_map { assert_eq!(iter.size_hint(), (3, Some(3))); } + #[test] + fn test_iter_mut_len() { + let xs = [(1i, 1i), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]; + + let mut map: HashMap = xs.iter().map(|&x| x).collect(); + + let mut iter = map.iter_mut(); + + for _ in iter.by_ref().take(3) {} + + assert_eq!(iter.len(), 3); + } + #[test] fn test_index() { let mut map: HashMap = HashMap::new(); diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 4003d3addf139..1293f45161d78 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -18,7 +18,7 @@ use default::Default; use fmt::Show; use fmt; use hash::{self, Hash}; -use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend}; +use iter::{Iterator, ExactSizeIterator, IteratorExt, FromIterator, Map, Chain, Extend}; use ops::{BitOr, BitAnd, BitXor, Sub}; use option::Option::{Some, None, self}; @@ -837,7 +837,11 @@ impl<'a, K> Iterator for Iter<'a, K> { type Item = &'a K; fn next(&mut self) -> Option<&'a K> { self.iter.next() } - fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable] +impl<'a, K> ExactSizeIterator for Iter<'a, K> { + fn len(&self) -> usize { self.iter.len() } } #[stable] @@ -845,15 +849,23 @@ impl Iterator for IntoIter { type Item = K; fn next(&mut self) -> Option { self.iter.next() } - fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable] +impl ExactSizeIterator for IntoIter { + fn len(&self) -> usize { self.iter.len() } } #[stable] -impl<'a, K: 'a> Iterator for Drain<'a, K> { +impl<'a, K> Iterator for Drain<'a, K> { type Item = K; fn next(&mut self) -> Option { self.iter.next() } - fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} +#[stable] +impl<'a, K> ExactSizeIterator for Drain<'a, K> { + fn len(&self) -> usize { self.iter.len() } } #[stable] @@ -875,7 +887,7 @@ impl<'a, T, S, H> Iterator for Intersection<'a, T, S> } } - fn size_hint(&self) -> (uint, Option) { + fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) } @@ -900,7 +912,7 @@ impl<'a, T, S, H> Iterator for Difference<'a, T, S> } } - fn size_hint(&self) -> (uint, Option) { + fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) } @@ -915,7 +927,7 @@ impl<'a, T, S, H> Iterator for SymmetricDifference<'a, T, S> type Item = &'a T; fn next(&mut self) -> Option<&'a T> { self.iter.next() } - fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } #[stable] @@ -927,7 +939,7 @@ impl<'a, T, S, H> Iterator for Union<'a, T, S> type Item = &'a T; fn next(&mut self) -> Option<&'a T> { self.iter.next() } - fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } #[cfg(test)] diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 456f3763b3916..f28b95dbe95c4 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -15,7 +15,7 @@ use self::BucketState::*; use clone::Clone; use cmp; use hash::{Hash, Hasher}; -use iter::{Iterator, count}; +use iter::{Iterator, ExactSizeIterator, count}; use marker::{Copy, Sized, self}; use mem::{min_align_of, size_of}; use mem; @@ -838,10 +838,13 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> { }) } - fn size_hint(&self) -> (uint, Option) { + fn size_hint(&self) -> (usize, Option) { (self.elems_left, Some(self.elems_left)) } } +impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { + fn len(&self) -> usize { self.elems_left } +} impl<'a, K, V> Iterator for IterMut<'a, K, V> { type Item = (&'a K, &'a mut V); @@ -856,10 +859,13 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { }) } - fn size_hint(&self) -> (uint, Option) { + fn size_hint(&self) -> (usize, Option) { (self.elems_left, Some(self.elems_left)) } } +impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { + fn len(&self) -> usize { self.elems_left } +} impl Iterator for IntoIter { type Item = (SafeHash, K, V); @@ -879,13 +885,16 @@ impl Iterator for IntoIter { }) } - fn size_hint(&self) -> (uint, Option) { + fn size_hint(&self) -> (usize, Option) { let size = self.table.size(); (size, Some(size)) } } +impl ExactSizeIterator for IntoIter { + fn len(&self) -> usize { self.table.size() } +} -impl<'a, K: 'a, V: 'a> Iterator for Drain<'a, K, V> { +impl<'a, K, V> Iterator for Drain<'a, K, V> { type Item = (SafeHash, K, V); #[inline] @@ -904,11 +913,14 @@ impl<'a, K: 'a, V: 'a> Iterator for Drain<'a, K, V> { }) } - fn size_hint(&self) -> (uint, Option) { + fn size_hint(&self) -> (usize, Option) { let size = self.table.size(); (size, Some(size)) } } +impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { + fn len(&self) -> usize { self.table.size() } +} #[unsafe_destructor] impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {