@@ -1514,54 +1514,44 @@ pub type SetMoveItems<K> =
1514
1514
/// println!("{}", *book);
1515
1515
/// }
1516
1516
/// ```
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
+ /// ```
1517
1543
#[ deriving( Clone ) ]
1518
1544
pub struct HashSet < T , H = RandomSipHasher > {
1519
1545
map : HashMap < T , ( ) , H >
1520
1546
}
1521
1547
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
-
1558
1548
impl < T : Hash + Eq > HashSet < T , RandomSipHasher > {
1559
- /// Create an empty HashSet
1549
+ /// Create an empty HashSet.
1560
1550
///
1561
1551
/// # Example
1562
1552
///
1563
1553
/// ```rust
1564
- /// # use std::collections::HashSet;
1554
+ /// use std::collections::HashSet;
1565
1555
/// let mut set: HashSet<int> = HashSet::new();
1566
1556
/// ```
1567
1557
#[ inline]
@@ -1575,7 +1565,7 @@ impl<T: Hash + Eq> HashSet<T, RandomSipHasher> {
1575
1565
/// # Example
1576
1566
///
1577
1567
/// ```rust
1578
- /// # use std::collections::HashSet;
1568
+ /// use std::collections::HashSet;
1579
1569
/// let mut set: HashSet<int> = HashSet::with_capacity(10);
1580
1570
/// ```
1581
1571
#[ inline]
@@ -1589,6 +1579,17 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1589
1579
/// keys.
1590
1580
///
1591
1581
/// 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
+ /// ```
1592
1593
#[ inline]
1593
1594
pub fn with_hasher ( hasher : H ) -> HashSet < T , H > {
1594
1595
HashSet :: with_capacity_and_hasher ( INITIAL_CAPACITY , hasher)
@@ -1601,6 +1602,17 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1601
1602
/// is designed to allow `HashSet`s to be resistant to attacks that
1602
1603
/// cause many collisions and very poor performance. Setting it
1603
1604
/// 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
+ /// ```
1604
1616
#[ inline]
1605
1617
pub fn with_capacity_and_hasher ( capacity : uint , hasher : H ) -> HashSet < T , H > {
1606
1618
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> {
1611
1623
/// # Example
1612
1624
///
1613
1625
/// ```rust
1614
- /// # use std::collections::HashSet;
1626
+ /// use std::collections::HashSet;
1615
1627
/// let mut set: HashSet<int> = HashSet::new();
1616
1628
/// set.reserve(10);
1617
1629
/// ```
@@ -1621,6 +1633,45 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1621
1633
1622
1634
/// Returns true if the hash set contains a value equivalent to the
1623
1635
/// 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
+ /// ```
1624
1675
pub fn contains_equiv < Q : Hash < S > + Equiv < T > > ( & self , value : & Q ) -> bool {
1625
1676
self . map . contains_key_equiv ( value)
1626
1677
}
@@ -1631,7 +1682,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1631
1682
/// # Example
1632
1683
///
1633
1684
/// ```rust
1634
- /// # use std::collections::HashSet;
1685
+ /// use std::collections::HashSet;
1686
+ ///
1635
1687
/// let mut set = HashSet::new();
1636
1688
/// set.insert("a");
1637
1689
/// set.insert("b");
@@ -1652,7 +1704,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1652
1704
/// # Example
1653
1705
///
1654
1706
/// ```rust
1655
- /// # use std::collections::HashSet;
1707
+ /// use std::collections::HashSet;
1708
+ ///
1656
1709
/// let mut set = HashSet::new();
1657
1710
/// set.insert("a".to_string());
1658
1711
/// set.insert("b".to_string());
@@ -1674,7 +1727,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1674
1727
/// # Example
1675
1728
///
1676
1729
/// ```rust
1677
- /// # use std::collections::HashSet;
1730
+ /// use std::collections::HashSet;
1731
+ ///
1678
1732
/// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1679
1733
/// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
1680
1734
///
@@ -1703,7 +1757,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1703
1757
/// # Example
1704
1758
///
1705
1759
/// ```rust
1706
- /// # use std::collections::HashSet;
1760
+ /// use std::collections::HashSet;
1761
+ ///
1707
1762
/// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1708
1763
/// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
1709
1764
///
@@ -1728,7 +1783,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1728
1783
/// # Example
1729
1784
///
1730
1785
/// ```rust
1731
- /// # use std::collections::HashSet;
1786
+ /// use std::collections::HashSet;
1787
+ ///
1732
1788
/// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1733
1789
/// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
1734
1790
///
@@ -1753,7 +1809,8 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1753
1809
/// # Example
1754
1810
///
1755
1811
/// ```rust
1756
- /// # use std::collections::HashSet;
1812
+ /// use std::collections::HashSet;
1813
+ ///
1757
1814
/// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1758
1815
/// let b: HashSet<int> = [4i, 2, 3, 4].iter().map(|&x| x).collect();
1759
1816
///
@@ -1771,6 +1828,43 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1771
1828
}
1772
1829
}
1773
1830
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
+
1774
1868
impl < T : Eq + Hash < S > + fmt:: Show , S , H : Hasher < S > > fmt:: Show for HashSet < T , H > {
1775
1869
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1776
1870
try!( write ! ( f, "{{" ) ) ;
0 commit comments