Add ExactSizeIterator impls for Hash{Map, Set, Table}

This commit also changes the return types of all `size_hint()` impls
in these files from (uint, Option<uint>) to (usize, Option<usize>).
This commit is contained in:
Chase Southwood 2015-01-10 20:07:42 -06:00
parent 099b411e08
commit c05338793b
3 changed files with 98 additions and 30 deletions

View File

@ -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<uint>) { self.inner.size_hint() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { 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<uint>) { self.inner.size_hint() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { 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<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
#[inline] fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable]
impl<K, V> ExactSizeIterator for IntoIter<K, V> {
#[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<uint>) { self.inner.size_hint() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { 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<uint>) { self.inner.size_hint() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { 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<uint>) {
self.inner.size_hint()
}
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { 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<int, int> = 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<int, int> = 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<int, int> = HashMap::new();

View File

@ -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<uint>) { self.iter.size_hint() }
fn size_hint(&self) -> (usize, Option<usize>) { 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<K> Iterator for IntoIter<K> {
type Item = K;
fn next(&mut self) -> Option<K> { self.iter.next() }
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
#[stable]
impl<K> ExactSizeIterator for IntoIter<K> {
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<K> { self.iter.next() }
fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
fn size_hint(&self) -> (usize, Option<usize>) { 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<uint>) {
fn size_hint(&self) -> (usize, Option<usize>) {
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<uint>) {
fn size_hint(&self) -> (usize, Option<usize>) {
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<uint>) { self.iter.size_hint() }
fn size_hint(&self) -> (usize, Option<usize>) { 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<uint>) { self.iter.size_hint() }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
#[cfg(test)]

View File

@ -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<uint>) {
fn size_hint(&self) -> (usize, Option<usize>) {
(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<uint>) {
fn size_hint(&self) -> (usize, Option<usize>) {
(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<K, V> Iterator for IntoIter<K, V> {
type Item = (SafeHash, K, V);
@ -879,13 +885,16 @@ impl<K, V> Iterator for IntoIter<K, V> {
})
}
fn size_hint(&self) -> (uint, Option<uint>) {
fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.table.size();
(size, Some(size))
}
}
impl<K, V> ExactSizeIterator for IntoIter<K, V> {
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<uint>) {
fn size_hint(&self) -> (usize, Option<usize>) {
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> {