From cf350ea5eb562fcfb67775ad4d847e441a8006a4 Mon Sep 17 00:00:00 2001 From: bluss Date: Fri, 19 Dec 2014 21:54:50 +0100 Subject: [PATCH] hashset: Clean up and rename the HashSet iterators This removes the type SetAlgebraItems and replaces it with the structs Intersection and Difference. Rename the existing HashSet iterators according to RFC #344: * SetItems -> Iter * SetMoveItems -> IntoIter * Remaining set combination iterators renamed to Union and SymmetricDifference [breaking-change] --- src/libstd/collections/hash/set.rs | 129 +++++++++++++++++++---------- 1 file changed, 83 insertions(+), 46 deletions(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 67c0f887832..99fe6696ec7 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -17,7 +17,7 @@ use fmt::Show; use fmt; use hash::{Hash, Hasher, RandomSipHasher}; -use iter::{Iterator, IteratorExt, FromIterator, Map, FilterMap, Chain, Repeat, Zip, Extend, repeat}; +use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend}; use option::Option::{Some, None, mod}; use result::Result::{Ok, Err}; @@ -250,8 +250,8 @@ pub fn contains_equiv + Equiv>(&self, value: &Q) -> bool { /// } /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn iter<'a>(&'a self) -> SetItems<'a, T> { - SetItems { iter: self.map.keys() } + pub fn iter<'a>(&'a self) -> Iter<'a, T> { + Iter { iter: self.map.keys() } } /// Creates a consuming iterator, that is, one that moves each value out @@ -275,10 +275,10 @@ pub fn iter<'a>(&'a self) -> SetItems<'a, T> { /// } /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn into_iter(self) -> SetMoveItems { + pub fn into_iter(self) -> IntoIter { fn first((a, _): (A, B)) -> A { a } - SetMoveItems { iter: self.map.into_iter().map(first) } + IntoIter { iter: self.map.into_iter().map(first) } } /// Visit the values representing the difference. @@ -304,14 +304,11 @@ fn first((a, _): (A, B)) -> A { a } /// assert_eq!(diff, [4i].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn difference<'a>(&'a self, other: &'a HashSet) -> SetAlgebraItems<'a, T, H> { - fn filter<'a, T, S, H>((other, elt): (&HashSet, &'a T)) -> Option<&'a T> where - T: Eq + Hash, H: Hasher - { - if !other.contains(elt) { Some(elt) } else { None } + pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, H> { + Difference { + iter: self.iter(), + other: other, } - - SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) } } /// Visit the values representing the symmetric difference. @@ -336,8 +333,8 @@ fn filter<'a, T, S, H>((other, elt): (&HashSet, &'a T)) -> Option<&'a T> w /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet) - -> SymDifferenceItems<'a, T, H> { - SymDifferenceItems { iter: self.difference(other).chain(other.difference(self)) } + -> SymmetricDifference<'a, T, H> { + SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } } /// Visit the values representing the intersection. @@ -358,14 +355,11 @@ pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet) /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn intersection<'a>(&'a self, other: &'a HashSet) -> SetAlgebraItems<'a, T, H> { - fn filter<'a, T, S, H>((other, elt): (&HashSet, &'a T)) -> Option<&'a T> where - T: Eq + Hash, H: Hasher - { - if other.contains(elt) { Some(elt) } else { None } + pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, H> { + Intersection { + iter: self.iter(), + other: other, } - - SetAlgebraItems { iter: repeat(other).zip(self.iter()).filter_map(filter) } } /// Visit the values representing the union. @@ -386,8 +380,8 @@ fn filter<'a, T, S, H>((other, elt): (&HashSet, &'a T)) -> Option<&'a T> w /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect()); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn union<'a>(&'a self, other: &'a HashSet) -> UnionItems<'a, T, H> { - UnionItems { iter: self.iter().chain(other.difference(self)) } + pub fn union<'a>(&'a self, other: &'a HashSet) -> Union<'a, T, H> { + Union { iter: self.iter().chain(other.difference(self)) } } /// Return the number of elements in the set @@ -617,58 +611,101 @@ fn default() -> HashSet { } /// HashSet iterator -pub struct SetItems<'a, K: 'a> { +pub struct Iter<'a, K: 'a> { iter: Keys<'a, K, ()> } /// HashSet move iterator -pub struct SetMoveItems { +pub struct IntoIter { iter: Map<(K, ()), K, MoveEntries, fn((K, ())) -> K> } -// `Repeat` is used to feed the filter closure an explicit capture -// of a reference to the other set -/// Set operations iterator, used directly for intersection and difference -pub struct SetAlgebraItems<'a, T: 'a, H: 'a> { - iter: FilterMap< - (&'a HashSet, &'a T), - &'a T, - Zip>, SetItems<'a, T>>, - for<'b> fn((&HashSet, &'b T)) -> Option<&'b T>, - > +/// Intersection iterator +pub struct Intersection<'a, T: 'a, H: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, +} + +/// Difference iterator +pub struct Difference<'a, T: 'a, H: 'a> { + // iterator of the first set + iter: Iter<'a, T>, + // the second set + other: &'a HashSet, } /// Symmetric difference iterator. -pub struct SymDifferenceItems<'a, T: 'a, H: 'a> { - iter: Chain, SetAlgebraItems<'a, T, H>> +pub struct SymmetricDifference<'a, T: 'a, H: 'a> { + iter: Chain, Difference<'a, T, H>> } /// Set union iterator. -pub struct UnionItems<'a, T: 'a, H: 'a> { - iter: Chain, SetAlgebraItems<'a, T, H>> +pub struct Union<'a, T: 'a, H: 'a> { + iter: Chain, Difference<'a, T, H>> } -impl<'a, K> Iterator<&'a K> for SetItems<'a, K> { +impl<'a, K> Iterator<&'a K> for Iter<'a, K> { fn next(&mut self) -> Option<&'a K> { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } -impl Iterator for SetMoveItems { +impl Iterator for IntoIter { fn next(&mut self) -> Option { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } -impl<'a, T, H> Iterator<&'a T> for SetAlgebraItems<'a, T, H> { - fn next(&mut self) -> Option<&'a T> { self.iter.next() } - fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } +impl<'a, T, S, H> Iterator<&'a T> for Intersection<'a, T, H> + where T: Eq + Hash, H: Hasher +{ + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } +} + +impl<'a, T, S, H> Iterator<&'a T> for Difference<'a, T, H> + where T: Eq + Hash, H: Hasher +{ + fn next(&mut self) -> Option<&'a T> { + loop { + match self.iter.next() { + None => return None, + Some(elt) => if !self.other.contains(elt) { + return Some(elt) + }, + } + } + } + + fn size_hint(&self) -> (uint, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) + } } -impl<'a, T, H> Iterator<&'a T> for SymDifferenceItems<'a, T, H> { +impl<'a, T, S, H> Iterator<&'a T> for SymmetricDifference<'a, T, H> + where T: Eq + Hash, H: Hasher +{ fn next(&mut self) -> Option<&'a T> { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } -impl<'a, T, H> Iterator<&'a T> for UnionItems<'a, T, H> { +impl<'a, T, S, H> Iterator<&'a T> for Union<'a, T, H> + where T: Eq + Hash, H: Hasher +{ fn next(&mut self) -> Option<&'a T> { self.iter.next() } fn size_hint(&self) -> (uint, Option) { self.iter.size_hint() } } -- 2.44.0