From db3989c3db26bc3b5d4d2fda20eb1bbe1d2296ed Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Wed, 17 Dec 2014 19:10:09 -0600 Subject: [PATCH] Implement BitOps for HashSet --- src/libstd/collections/hash/set.rs | 119 ++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 4 deletions(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index f587669d3da..0024c98b074 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -11,21 +11,20 @@ // ignore-lexer-test FIXME #15883 use borrow::BorrowFrom; +use clone::Clone; use cmp::{Eq, Equiv, PartialEq}; use core::kinds::Sized; use default::Default; use fmt::Show; use fmt; use hash::{Hash, Hasher, RandomSipHasher}; -use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend}; +use iter::{Iterator, IteratorExt, IteratorCloneExt, FromIterator, Map, Chain, Extend}; +use ops::{BitOr, BitAnd, BitXor, Sub}; use option::Option::{Some, None, mod}; use result::Result::{Ok, Err}; use super::map::{mod, HashMap, MoveEntries, Keys, INITIAL_CAPACITY}; -// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub - - // Future Optimization (FIXME!) // ============================= // @@ -618,6 +617,118 @@ impl, S, H: Hasher + Default> Default for HashSet { } } +#[unstable = "matches collection reform specification, waiting for dust to settle"] +impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> +BitOr<&'b HashSet, HashSet> for &'a HashSet { + /// Returns the union of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet = vec![3, 4, 5].into_iter().collect(); + /// + /// let set: HashSet = &a | &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 3, 4, 5]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitor(self, rhs: &HashSet) -> HashSet { + self.union(rhs).cloned().collect() + } +} + +#[unstable = "matches collection reform specification, waiting for dust to settle"] +impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> +BitAnd<&'b HashSet, HashSet> for &'a HashSet { + /// Returns the intersection of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet = vec![2, 3, 4].into_iter().collect(); + /// + /// let set: HashSet = &a & &b; + /// + /// let mut i = 0; + /// let expected = [2, 3]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitand(self, rhs: &HashSet) -> HashSet { + self.intersection(rhs).cloned().collect() + } +} + +#[unstable = "matches collection reform specification, waiting for dust to settle"] +impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> +BitXor<&'b HashSet, HashSet> for &'a HashSet { + /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet = vec![3, 4, 5].into_iter().collect(); + /// + /// let set: HashSet = &a ^ &b; + /// + /// let mut i = 0; + /// let expected = [1, 2, 4, 5]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn bitxor(self, rhs: &HashSet) -> HashSet { + self.symmetric_difference(rhs).cloned().collect() + } +} + +#[unstable = "matches collection reform specification, waiting for dust to settle"] +impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> +Sub<&'b HashSet, HashSet> for &'a HashSet { + /// Returns the difference of `self` and `rhs` as a new `HashSet`. + /// + /// # Examples + /// + /// ``` + /// use std::collections::HashSet; + /// + /// let a: HashSet = vec![1, 2, 3].into_iter().collect(); + /// let b: HashSet = vec![3, 4, 5].into_iter().collect(); + /// + /// let set: HashSet = &a - &b; + /// + /// let mut i = 0; + /// let expected = [1, 2]; + /// for x in set.iter() { + /// assert!(expected.contains(x)); + /// i += 1; + /// } + /// assert_eq!(i, expected.len()); + /// ``` + fn sub(self, rhs: &HashSet) -> HashSet { + self.difference(rhs).cloned().collect() + } +} + /// HashSet iterator pub struct Iter<'a, K: 'a> { iter: Keys<'a, K, ()>