@@ -1514,49 +1514,39 @@ 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
///
@@ -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) }
@@ -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
}
@@ -1771,7 +1822,154 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
1771
1822
}
1772
1823
}
1773
1824
1825
+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > PartialEq for HashSet < T , H > {
1826
+ /// Partial equality between sets.
1827
+ ///
1828
+ /// # Example
1829
+ ///
1830
+ /// ```rust
1831
+ /// # use std::collections::HashSet;
1832
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1833
+ /// let b: HashSet<int> = [1i, 2, 3, 4].iter().map(|&x| x).collect();
1834
+ /// let c: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1835
+ ///
1836
+ /// assert!(a.eq(&c));
1837
+ ///
1838
+ /// // eq and ne defines the == and != operators
1839
+ /// assert!(a == c);
1840
+ /// assert!(a != b);
1841
+ /// ```
1842
+ fn eq ( & self , other : & HashSet < T , H > ) -> bool {
1843
+ if self . len ( ) != other. len ( ) { return false ; }
1844
+
1845
+ self . iter ( ) . all ( |key| other. contains ( key) )
1846
+ }
1847
+ }
1848
+
1849
+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Eq for HashSet < T , H > { }
1850
+
1851
+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Collection for HashSet < T , H > {
1852
+ /// Return the number of elements in the set.
1853
+ ///
1854
+ /// # Example
1855
+ ///
1856
+ /// ```rust
1857
+ /// # use std::collections::HashSet;
1858
+ /// let set: HashSet<int> = [1i, 2, 3, 2].iter().map(|&x| x).collect();
1859
+ /// assert_eq!(set.len(), 3);
1860
+ /// ```
1861
+ fn len ( & self ) -> uint { self . map . len ( ) }
1862
+ }
1863
+
1864
+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Mutable for HashSet < T , H > {
1865
+ /// Clear the set. Keeps the allocated memory for reuse.
1866
+ ///
1867
+ /// # Example
1868
+ ///
1869
+ /// ```rust
1870
+ /// # use std::collections::HashSet;
1871
+ /// let mut set: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1872
+ /// set.clear();
1873
+ /// assert!(set.is_empty());
1874
+ /// ```
1875
+ fn clear ( & mut self ) { self . map . clear ( ) }
1876
+ }
1877
+
1878
+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > Set < T > for HashSet < T , H > {
1879
+ /// Return true if `value` is contained by the set.
1880
+ ///
1881
+ /// # Example
1882
+ ///
1883
+ /// ```rust
1884
+ /// # use std::collections::HashSet;
1885
+ /// let set: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1886
+ /// assert_eq!(set.contains(&1), true);
1887
+ /// assert_eq!(set.contains(&4), false);
1888
+ /// ```
1889
+ fn contains ( & self , value : & T ) -> bool { self . map . contains_key ( value) }
1890
+
1891
+ /// Return true if the set is disjoint with `other`.
1892
+ ///
1893
+ /// # Example
1894
+ ///
1895
+ /// ```rust
1896
+ /// # use std::collections::HashSet;
1897
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1898
+ /// let mut b: HashSet<int> = HashSet::new();
1899
+ ///
1900
+ /// assert_eq!(a.is_disjoint(&b), true);
1901
+ /// b.insert(4);
1902
+ /// assert_eq!(a.is_disjoint(&b), true);
1903
+ /// b.insert(1);
1904
+ /// assert_eq!(a.is_disjoint(&b), false);
1905
+ /// ```
1906
+ fn is_disjoint ( & self , other : & HashSet < T , H > ) -> bool {
1907
+ self . iter ( ) . all ( |v| !other. contains ( v) )
1908
+ }
1909
+
1910
+ /// Return true if the set is a subset of `other`.
1911
+ ///
1912
+ /// # Example
1913
+ ///
1914
+ /// ```rust
1915
+ /// # use std::collections::HashSet;
1916
+ /// let sup: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1917
+ /// let mut set: HashSet<int> = HashSet::new();
1918
+ ///
1919
+ /// assert_eq!(set.is_subset(&sup), true);
1920
+ /// set.insert(2);
1921
+ /// assert_eq!(set.is_subset(&sup), true);
1922
+ /// set.insert(4);
1923
+ /// assert_eq!(set.is_subset(&sup), false);
1924
+ /// ```
1925
+ fn is_subset ( & self , other : & HashSet < T , H > ) -> bool {
1926
+ self . iter ( ) . all ( |v| other. contains ( v) )
1927
+ }
1928
+ }
1929
+
1930
+ impl < T : Eq + Hash < S > , S , H : Hasher < S > > MutableSet < T > for HashSet < T , H > {
1931
+ /// Insert an element.
1932
+ ///
1933
+ /// # Example
1934
+ ///
1935
+ /// ```rust
1936
+ /// # use std::collections::HashSet;
1937
+ /// let mut set = HashSet::new();
1938
+ /// set.insert(2i);
1939
+ /// set.insert(2i);
1940
+ /// assert_eq!(set.len(), 1);
1941
+ /// ```
1942
+ fn insert ( & mut self , value : T ) -> bool { self . map . insert ( value, ( ) ) }
1943
+
1944
+ /// Remove an element.
1945
+ ///
1946
+ /// # Example
1947
+ ///
1948
+ /// ```rust
1949
+ /// # use std::collections::HashSet;
1950
+ /// let mut set = HashSet::new();
1951
+ /// set.insert(2i);
1952
+ ///
1953
+ /// // Return boolean success flag.
1954
+ /// assert_eq!(set.remove(&2), true);
1955
+ /// assert_eq!(set.remove(&2), false);
1956
+ /// ```
1957
+ fn remove ( & mut self , value : & T ) -> bool { self . map . remove ( value) }
1958
+ }
1959
+
1960
+
1774
1961
impl < T : Eq + Hash < S > + fmt:: Show , S , H : Hasher < S > > fmt:: Show for HashSet < T , H > {
1962
+ /// Implement the `Show` trait for easy output format. The values in the
1963
+ /// set must also implement `Show`.
1964
+ ///
1965
+ /// # Example
1966
+ ///
1967
+ /// ```rust
1968
+ /// # use std::collections::HashSet;
1969
+ /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1970
+ /// // Will call .fmt() to print, in some order.
1971
+ /// println!("{}", a);
1972
+ /// ```
1775
1973
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1776
1974
try!( write ! ( f, "{{" ) ) ;
1777
1975
@@ -1785,6 +1983,17 @@ impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
1785
1983
}
1786
1984
1787
1985
impl < T : Eq + Hash < S > , S , H : Hasher < S > + Default > FromIterator < T > for HashSet < T , H > {
1986
+ /// Build a set from an external iterator.
1987
+ ///
1988
+ /// # Example
1989
+ ///
1990
+ /// ```rust
1991
+ /// # use std::collections::HashSet;
1992
+ /// let values = vec!(1i, 2, 3);
1993
+ /// let set: HashSet<int> = values.move_iter().collect();
1994
+ /// let another_set: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
1995
+ /// assert_eq!(set, another_set);
1996
+ /// ```
1788
1997
fn from_iter < I : Iterator < T > > ( iter : I ) -> HashSet < T , H > {
1789
1998
let ( lower, _) = iter. size_hint ( ) ;
1790
1999
let mut set = HashSet :: with_capacity_and_hasher ( lower, Default :: default ( ) ) ;
@@ -1794,6 +2003,18 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T,
1794
2003
}
1795
2004
1796
2005
impl < T : Eq + Hash < S > , S , H : Hasher < S > + Default > Extendable < T > for HashSet < T , H > {
2006
+ /// Extend the set with the values yielded by an iterator.
2007
+ ///
2008
+ /// # Example
2009
+ ///
2010
+ /// ```rust
2011
+ /// # use std::collections::HashSet;
2012
+ /// let values = vec!(1i, 2, 3);
2013
+ /// let mut set = HashSet::new();
2014
+ /// set.insert(0i);
2015
+ /// set.extend(values.move_iter());
2016
+ /// assert_eq!(set.len(), 4);
2017
+ /// ```
1797
2018
fn extend < I : Iterator < T > > ( & mut self , mut iter : I ) {
1798
2019
for k in iter {
1799
2020
self . insert ( k) ;
@@ -1802,6 +2023,15 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H>
1802
2023
}
1803
2024
1804
2025
impl < T : Eq + Hash < S > , S , H : Hasher < S > + Default > Default for HashSet < T , H > {
2026
+ /// Create a default set.
2027
+ ///
2028
+ /// # Example
2029
+ ///
2030
+ /// ```rust
2031
+ /// # use std::collections::HashSet;
2032
+ /// use std::default::Default;
2033
+ /// let mut set: HashSet<int> = Default::default();
2034
+ /// ```
1805
2035
fn default ( ) -> HashSet < T , H > {
1806
2036
HashSet :: with_hasher ( Default :: default ( ) )
1807
2037
}
0 commit comments