@@ -1514,49 +1514,39 @@ 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 ///
@@ -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) }
@@ -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 }
@@ -1771,7 +1822,154 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
17711822 }
17721823}
17731824
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+
17741961impl < 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+ /// ```
17751973 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
17761974 try!( write ! ( f, "{{" ) ) ;
17771975
@@ -1785,6 +1983,17 @@ impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
17851983}
17861984
17871985impl < 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+ /// ```
17881997 fn from_iter < I : Iterator < T > > ( iter : I ) -> HashSet < T , H > {
17891998 let ( lower, _) = iter. size_hint ( ) ;
17901999 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,
17942003}
17952004
17962005impl < 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+ /// ```
17972018 fn extend < I : Iterator < T > > ( & mut self , mut iter : I ) {
17982019 for k in iter {
17992020 self . insert ( k) ;
@@ -1802,6 +2023,15 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H>
18022023}
18032024
18042025impl < 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+ /// ```
18052035 fn default ( ) -> HashSet < T , H > {
18062036 HashSet :: with_hasher ( Default :: default ( ) )
18072037 }
0 commit comments