@@ -1514,54 +1514,44 @@ pub type SetMoveItems<K> =
15141514/// println!("{}", *book);
15151515/// }
15161516/// ```
1517+ ///
1518+ /// The easiest way to use `HashSet` with a custom type is to derive
1519+ /// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the
1520+ /// future be implied by `Eq`.
1521+ ///
1522+ /// ```rust
1523+ /// use std::collections::HashSet;
1524+ ///
1525+ /// #[deriving(Hash, Eq, PartialEq, Show)]
1526+ /// struct Viking<'a> {
1527+ /// name: &'a str,
1528+ /// power: uint,
1529+ /// }
1530+ ///
1531+ /// let mut vikings = HashSet::new();
1532+ ///
1533+ /// vikings.insert(Viking { name: "Einar", power: 9u });
1534+ /// vikings.insert(Viking { name: "Einar", power: 9u });
1535+ /// vikings.insert(Viking { name: "Olaf", power: 4u });
1536+ /// vikings.insert(Viking { name: "Harald", power: 8u });
1537+ ///
1538+ /// // Use derived implementation to print the vikings.
1539+ /// for x in vikings.iter() {
1540+ /// println!("{}", x);
1541+ /// }
1542+ /// ```
15171543#[ deriving( Clone ) ]
15181544pub struct HashSet < T , H = RandomSipHasher > {
15191545 map : HashMap < T , ( ) , H >
15201546}
15211547
1522- impl < T : Eq + Hash < S > , S , H : Hasher < S > > PartialEq for HashSet < T , H > {
1523- fn eq ( & self , other : & HashSet < T , H > ) -> bool {
1524- if self . len ( ) != other. len ( ) { return false ; }
1525-
1526- self . iter ( ) . all ( |key| other. contains ( key) )
1527- }
1528- }
1529-
1530- impl < T : Eq + Hash < S > , S , H : Hasher < S > > Eq for HashSet < T , H > { }
1531-
1532- impl < T : Eq + Hash < S > , S , H : Hasher < S > > Collection for HashSet < T , H > {
1533- fn len ( & self ) -> uint { self . map . len ( ) }
1534- }
1535-
1536- impl < T : Eq + Hash < S > , S , H : Hasher < S > > Mutable for HashSet < T , H > {
1537- fn clear ( & mut self ) { self . map . clear ( ) }
1538- }
1539-
1540- impl < T : Eq + Hash < S > , S , H : Hasher < S > > Set < T > for HashSet < T , H > {
1541- fn contains ( & self , value : & T ) -> bool { self . map . contains_key ( value) }
1542-
1543- fn is_disjoint ( & self , other : & HashSet < T , H > ) -> bool {
1544- self . iter ( ) . all ( |v| !other. contains ( v) )
1545- }
1546-
1547- fn is_subset ( & self , other : & HashSet < T , H > ) -> bool {
1548- self . iter ( ) . all ( |v| other. contains ( v) )
1549- }
1550- }
1551-
1552- impl < T : Eq + Hash < S > , S , H : Hasher < S > > MutableSet < T > for HashSet < T , H > {
1553- fn insert ( & mut self , value : T ) -> bool { self . map . insert ( value, ( ) ) }
1554-
1555- fn remove ( & mut self , value : & T ) -> bool { self . map . remove ( value) }
1556- }
1557-
15581548impl < T : Hash + Eq > HashSet < T , RandomSipHasher > {
1559- /// Create an empty HashSet
1549+ /// Create an empty HashSet.
15601550 ///
15611551 /// # Example
15621552 ///
15631553 /// ```rust
1564- /// # use std::collections::HashSet;
1554+ /// use std::collections::HashSet;
15651555 /// let mut set: HashSet<int> = HashSet::new();
15661556 /// ```
15671557 #[ inline]
@@ -1575,7 +1565,7 @@ impl<T: Hash + Eq> HashSet<T, RandomSipHasher> {
15751565 /// # Example
15761566 ///
15771567 /// ```rust
1578- /// # use std::collections::HashSet;
1568+ /// use std::collections::HashSet;
15791569 /// let mut set: HashSet<int> = HashSet::with_capacity(10);
15801570 /// ```
15811571 #[ inline]
@@ -1589,6 +1579,17 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
15891579 /// keys.
15901580 ///
15911581 /// The hash set is also created with the default initial capacity.
1582+ ///
1583+ /// # Example
1584+ ///
1585+ /// ```rust
1586+ /// use std::collections::HashSet;
1587+ /// use std::hash::sip::SipHasher;
1588+ ///
1589+ /// let h = SipHasher::new();
1590+ /// let mut set = HashSet::with_hasher(h);
1591+ /// set.insert(2u);
1592+ /// ```
15921593 #[ inline]
15931594 pub fn with_hasher ( hasher : H ) -> HashSet < T , H > {
15941595 HashSet :: with_capacity_and_hasher ( INITIAL_CAPACITY , hasher)
@@ -1601,6 +1602,17 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
16011602 /// is designed to allow `HashSet`s to be resistant to attacks that
16021603 /// cause many collisions and very poor performance. Setting it
16031604 /// manually using this function can expose a DoS attack vector.
1605+ ///
1606+ /// # Example
1607+ ///
1608+ /// ```rust
1609+ /// use std::collections::HashSet;
1610+ /// use std::hash::sip::SipHasher;
1611+ ///
1612+ /// let h = SipHasher::new();
1613+ /// let mut set = HashSet::with_capacity_and_hasher(10u, h);
1614+ /// set.insert(1i);
1615+ /// ```
16041616 #[ inline]
16051617 pub fn with_capacity_and_hasher ( capacity : uint , hasher : H ) -> HashSet < T , H > {
16061618 HashSet { map : HashMap :: with_capacity_and_hasher ( capacity, hasher) }
@@ -1611,7 +1623,7 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
16111623 /// # Example
16121624 ///
16131625 /// ```rust
1614- /// # use std::collections::HashSet;
1626+ /// use std::collections::HashSet;
16151627 /// let mut set: HashSet<int> = HashSet::new();
16161628 /// set.reserve(10);
16171629 /// ```
@@ -1621,6 +1633,45 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
16211633
16221634 /// Returns true if the hash set contains a value equivalent to the
16231635 /// given query value.
1636+ ///
1637+ /// # Example
1638+ ///
1639+ /// This is a slightly silly example where we define the number's
1640+ /// parity as the equivilance class. It is important that the
1641+ /// values hash the same, which is why we implement `Hash`.
1642+ ///
1643+ /// ```rust
1644+ /// use std::collections::HashSet;
1645+ /// use std::hash::Hash;
1646+ /// use std::hash::sip::SipState;
1647+ ///
1648+ /// #[deriving(Eq, PartialEq)]
1649+ /// struct EvenOrOdd {
1650+ /// num: uint
1651+ /// };
1652+ ///
1653+ /// impl Hash for EvenOrOdd {
1654+ /// fn hash(&self, state: &mut SipState) {
1655+ /// let parity = self.num % 2;
1656+ /// parity.hash(state);
1657+ /// }
1658+ /// }
1659+ ///
1660+ /// impl Equiv<EvenOrOdd> for EvenOrOdd {
1661+ /// fn equiv(&self, other: &EvenOrOdd) -> bool {
1662+ /// self.num % 2 == other.num % 2
1663+ /// }
1664+ /// }
1665+ ///
1666+ /// let mut set = HashSet::new();
1667+ /// set.insert(EvenOrOdd { num: 3u });
1668+ ///
1669+ /// assert!(set.contains_equiv(&EvenOrOdd { num: 3u }));
1670+ /// assert!(set.contains_equiv(&EvenOrOdd { num: 5u }));
1671+ /// assert!(!set.contains_equiv(&EvenOrOdd { num: 4u }));
1672+ /// assert!(!set.contains_equiv(&EvenOrOdd { num: 2u }));
1673+ ///
1674+ /// ```
16241675 pub fn contains_equiv < Q : Hash < S > + Equiv < T > > ( & self , value : & Q ) -> bool {
16251676 self . map . contains_key_equiv ( value)
16261677 }
@@ -1631,7 +1682,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
16311682 /// # Example
16321683 ///
16331684 /// ```rust
1634- /// # use std::collections::HashSet;
1685+ /// use std::collections::HashSet;
1686+ ///
16351687 /// let mut set = HashSet::new();
16361688 /// set.insert("a");
16371689 /// set.insert("b");
@@ -1652,7 +1704,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
16521704 /// # Example
16531705 ///
16541706 /// ```rust
1655- /// # use std::collections::HashSet;
1707+ /// use std::collections::HashSet;
1708+ ///
16561709 /// let mut set = HashSet::new();
16571710 /// set.insert("a".to_string());
16581711 /// set.insert("b".to_string());
@@ -1674,7 +1727,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
16741727 /// # Example
16751728 ///
16761729 /// ```rust
1677- /// # use std::collections::HashSet;
1730+ /// use std::collections::HashSet;
1731+ ///
16781732 /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
16791733 /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
16801734 ///
@@ -1703,7 +1757,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
17031757 /// # Example
17041758 ///
17051759 /// ```rust
1706- /// # use std::collections::HashSet;
1760+ /// use std::collections::HashSet;
1761+ ///
17071762 /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
17081763 /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
17091764 ///
@@ -1728,7 +1783,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
17281783 /// # Example
17291784 ///
17301785 /// ```rust
1731- /// # use std::collections::HashSet;
1786+ /// use std::collections::HashSet;
1787+ ///
17321788 /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
17331789 /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
17341790 ///
@@ -1753,7 +1809,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
17531809 /// # Example
17541810 ///
17551811 /// ```rust
1756- /// # use std::collections::HashSet;
1812+ /// use std::collections::HashSet;
1813+ ///
17571814 /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
17581815 /// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
17591816 ///
@@ -1771,6 +1828,43 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
17711828 }
17721829}
17731830
1831+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > PartialEq for HashSet < T , H > {
1832+ fn eq ( & self , other : & HashSet < T , H > ) -> bool {
1833+ if self . len ( ) != other. len ( ) { return false ; }
1834+
1835+ self . iter ( ) . all ( |key| other. contains ( key) )
1836+ }
1837+ }
1838+
1839+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Eq for HashSet < T , H > { }
1840+
1841+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Collection for HashSet < T , H > {
1842+ fn len ( & self ) -> uint { self . map . len ( ) }
1843+ }
1844+
1845+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Mutable for HashSet < T , H > {
1846+ fn clear ( & mut self ) { self . map . clear ( ) }
1847+ }
1848+
1849+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Set < T > for HashSet < T , H > {
1850+ fn contains ( & self , value : & T ) -> bool { self . map . contains_key ( value) }
1851+
1852+ fn is_disjoint ( & self , other : & HashSet < T , H > ) -> bool {
1853+ self . iter ( ) . all ( |v| !other. contains ( v) )
1854+ }
1855+
1856+ fn is_subset ( & self , other : & HashSet < T , H > ) -> bool {
1857+ self . iter ( ) . all ( |v| other. contains ( v) )
1858+ }
1859+ }
1860+
1861+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > MutableSet < T > for HashSet < T , H > {
1862+ fn insert ( & mut self , value : T ) -> bool { self . map . insert ( value, ( ) ) }
1863+
1864+ fn remove ( & mut self , value : & T ) -> bool { self . map . remove ( value) }
1865+ }
1866+
1867+
17741868impl < T : Eq + Hash < S > + fmt:: Show , S , H : Hasher < S > > fmt:: Show for HashSet < T , H > {
17751869 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
17761870 try!( write ! ( f, "{{" ) ) ;
0 commit comments