about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-12-22 12:48:09 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-12-22 12:48:09 -0800
commit2cc9baccc783d5ff6e0f8fa27c38e2ddddfd71b7 (patch)
tree7346a3a55816a1f0cb16b8176846857ab513faef /src/libstd
parent55cf032f43c04e2c884589dd8737b9ac58fcab20 (diff)
parentdb3989c3db26bc3b5d4d2fda20eb1bbe1d2296ed (diff)
downloadrust-2cc9baccc783d5ff6e0f8fa27c38e2ddddfd71b7.tar.gz
rust-2cc9baccc783d5ff6e0f8fa27c38e2ddddfd71b7.zip
rollup merge of #20125: csouth3/hashset-bitops
Now that #19448 has landed in a snapshot, we can add proper by-value operator overloads for `HashSet`.  The behavior of these operator overloads is consistent with rust-lang/rfcs#235.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/collections/hash/set.rs119
1 files 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<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
     }
 }
 
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+BitOr<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the union of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &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<T, H>) -> HashSet<T, H> {
+        self.union(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+BitAnd<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &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<T, H>) -> HashSet<T, H> {
+        self.intersection(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+BitXor<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &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<T, H>) -> HashSet<T, H> {
+        self.symmetric_difference(rhs).cloned().collect()
+    }
+}
+
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
+Sub<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+    /// Returns the difference of `self` and `rhs` as a new `HashSet<T, H>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: HashSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: HashSet<int> = &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<T, H>) -> HashSet<T, H> {
+        self.difference(rhs).cloned().collect()
+    }
+}
+
 /// HashSet iterator
 pub struct Iter<'a, K: 'a> {
     iter: Keys<'a, K, ()>