Skip to content

Commit

Permalink
Add ExactSizeIterator impls for Hash{Map, Set, Table}
Browse files Browse the repository at this point in the history
This commit also changes the return types of all `size_hint()` impls
in these files from (uint, Option<uint>) to (usize, Option<usize>).
  • Loading branch information
csouth3 committed Jan 11, 2015
1 parent 099b411 commit c053387
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 30 deletions.
74 changes: 59 additions & 15 deletions src/libstd/collections/hash/map.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -1384,53 +1384,71 @@ 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]
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]
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]
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]
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"]
Expand Down Expand Up @@ -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)];
Expand All @@ -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();
Expand Down
30 changes: 21 additions & 9 deletions src/libstd/collections/hash/set.rs
Expand Up @@ -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};

Expand Down Expand Up @@ -837,23 +837,35 @@ 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]
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]
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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]
Expand All @@ -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)]
Expand Down
24 changes: 18 additions & 6 deletions src/libstd/collections/hash/table.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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]
Expand All @@ -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> {
Expand Down

0 comments on commit c053387

Please sign in to comment.