ahash/
hash_set.rs

1use crate::RandomState;
2use std::collections::{hash_set, HashSet};
3use std::fmt::{self, Debug};
4use std::hash::{BuildHasher, Hash};
5use std::iter::FromIterator;
6use std::ops::{BitAnd, BitOr, BitXor, Deref, DerefMut, Sub};
7
8#[cfg(feature = "serde")]
9use serde::{
10    de::{Deserialize, Deserializer},
11    ser::{Serialize, Serializer},
12};
13
14/// A [`HashSet`](std::collections::HashSet) using [`RandomState`](crate::RandomState) to hash the items.
15/// (Requires the `std` feature to be enabled.)
16#[derive(Clone)]
17pub struct AHashSet<T, S = RandomState>(HashSet<T, S>);
18
19impl<T> From<HashSet<T, RandomState>> for AHashSet<T> {
20    fn from(item: HashSet<T, RandomState>) -> Self {
21        AHashSet(item)
22    }
23}
24
25impl<T, const N: usize> From<[T; N]> for AHashSet<T>
26where
27    T: Eq + Hash,
28{
29    /// # Examples
30    ///
31    /// ```
32    /// use ahash::AHashSet;
33    ///
34    /// let set1 = AHashSet::from([1, 2, 3, 4]);
35    /// let set2: AHashSet<_> = [1, 2, 3, 4].into();
36    /// assert_eq!(set1, set2);
37    /// ```
38    fn from(arr: [T; N]) -> Self {
39        Self::from_iter(arr)
40    }
41}
42
43impl<T> Into<HashSet<T, RandomState>> for AHashSet<T> {
44    fn into(self) -> HashSet<T, RandomState> {
45        self.0
46    }
47}
48
49impl<T> AHashSet<T, RandomState> {
50    /// This crates a hashset using [RandomState::new].
51    /// See the documentation in [RandomSource] for notes about key strength.
52    pub fn new() -> Self {
53        AHashSet(HashSet::with_hasher(RandomState::new()))
54    }
55
56    /// This crates a hashset with the specified capacity using [RandomState::new].
57    /// See the documentation in [RandomSource] for notes about key strength.
58    pub fn with_capacity(capacity: usize) -> Self {
59        AHashSet(HashSet::with_capacity_and_hasher(capacity, RandomState::new()))
60    }
61}
62
63impl<T, S> AHashSet<T, S>
64where
65    S: BuildHasher,
66{
67    pub fn with_hasher(hash_builder: S) -> Self {
68        AHashSet(HashSet::with_hasher(hash_builder))
69    }
70
71    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
72        AHashSet(HashSet::with_capacity_and_hasher(capacity, hash_builder))
73    }
74}
75
76impl<T, S> Deref for AHashSet<T, S> {
77    type Target = HashSet<T, S>;
78    fn deref(&self) -> &Self::Target {
79        &self.0
80    }
81}
82
83impl<T, S> DerefMut for AHashSet<T, S> {
84    fn deref_mut(&mut self) -> &mut Self::Target {
85        &mut self.0
86    }
87}
88
89impl<T, S> PartialEq for AHashSet<T, S>
90where
91    T: Eq + Hash,
92    S: BuildHasher,
93{
94    fn eq(&self, other: &AHashSet<T, S>) -> bool {
95        self.0.eq(&other.0)
96    }
97}
98
99impl<T, S> Eq for AHashSet<T, S>
100where
101    T: Eq + Hash,
102    S: BuildHasher,
103{
104}
105
106impl<T, S> BitOr<&AHashSet<T, S>> for &AHashSet<T, S>
107where
108    T: Eq + Hash + Clone,
109    S: BuildHasher + Default,
110{
111    type Output = AHashSet<T, S>;
112
113    /// Returns the union of `self` and `rhs` as a new `AHashSet<T, S>`.
114    ///
115    /// # Examples
116    ///
117    /// ```
118    /// use ahash::AHashSet;
119    ///
120    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
121    /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect();
122    ///
123    /// let set = &a | &b;
124    ///
125    /// let mut i = 0;
126    /// let expected = [1, 2, 3, 4, 5];
127    /// for x in &set {
128    ///     assert!(expected.contains(x));
129    ///     i += 1;
130    /// }
131    /// assert_eq!(i, expected.len());
132    /// ```
133    fn bitor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
134        AHashSet(self.0.bitor(&rhs.0))
135    }
136}
137
138impl<T, S> BitAnd<&AHashSet<T, S>> for &AHashSet<T, S>
139where
140    T: Eq + Hash + Clone,
141    S: BuildHasher + Default,
142{
143    type Output = AHashSet<T, S>;
144
145    /// Returns the intersection of `self` and `rhs` as a new `AHashSet<T, S>`.
146    ///
147    /// # Examples
148    ///
149    /// ```
150    /// use ahash::AHashSet;
151    ///
152    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
153    /// let b: AHashSet<_> = vec![2, 3, 4].into_iter().collect();
154    ///
155    /// let set = &a & &b;
156    ///
157    /// let mut i = 0;
158    /// let expected = [2, 3];
159    /// for x in &set {
160    ///     assert!(expected.contains(x));
161    ///     i += 1;
162    /// }
163    /// assert_eq!(i, expected.len());
164    /// ```
165    fn bitand(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
166        AHashSet(self.0.bitand(&rhs.0))
167    }
168}
169
170impl<T, S> BitXor<&AHashSet<T, S>> for &AHashSet<T, S>
171where
172    T: Eq + Hash + Clone,
173    S: BuildHasher + Default,
174{
175    type Output = AHashSet<T, S>;
176
177    /// Returns the symmetric difference of `self` and `rhs` as a new `AHashSet<T, S>`.
178    ///
179    /// # Examples
180    ///
181    /// ```
182    /// use ahash::AHashSet;
183    ///
184    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
185    /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect();
186    ///
187    /// let set = &a ^ &b;
188    ///
189    /// let mut i = 0;
190    /// let expected = [1, 2, 4, 5];
191    /// for x in &set {
192    ///     assert!(expected.contains(x));
193    ///     i += 1;
194    /// }
195    /// assert_eq!(i, expected.len());
196    /// ```
197    fn bitxor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
198        AHashSet(self.0.bitxor(&rhs.0))
199    }
200}
201
202impl<T, S> Sub<&AHashSet<T, S>> for &AHashSet<T, S>
203where
204    T: Eq + Hash + Clone,
205    S: BuildHasher + Default,
206{
207    type Output = AHashSet<T, S>;
208
209    /// Returns the difference of `self` and `rhs` as a new `AHashSet<T, S>`.
210    ///
211    /// # Examples
212    ///
213    /// ```
214    /// use ahash::AHashSet;
215    ///
216    /// let a: AHashSet<_> = vec![1, 2, 3].into_iter().collect();
217    /// let b: AHashSet<_> = vec![3, 4, 5].into_iter().collect();
218    ///
219    /// let set = &a - &b;
220    ///
221    /// let mut i = 0;
222    /// let expected = [1, 2];
223    /// for x in &set {
224    ///     assert!(expected.contains(x));
225    ///     i += 1;
226    /// }
227    /// assert_eq!(i, expected.len());
228    /// ```
229    fn sub(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> {
230        AHashSet(self.0.sub(&rhs.0))
231    }
232}
233
234impl<T, S> Debug for AHashSet<T, S>
235where
236    T: Debug,
237    S: BuildHasher,
238{
239    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
240        self.0.fmt(fmt)
241    }
242}
243
244impl<T> FromIterator<T> for AHashSet<T, RandomState>
245where
246    T: Eq + Hash,
247{
248    /// This crates a hashset from the provided iterator using [RandomState::new].
249    /// See the documentation in [RandomSource] for notes about key strength.
250    #[inline]
251    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> AHashSet<T> {
252        let mut inner = HashSet::with_hasher(RandomState::new());
253        inner.extend(iter);
254        AHashSet(inner)
255    }
256}
257
258impl<'a, T, S> IntoIterator for &'a AHashSet<T, S> {
259    type Item = &'a T;
260    type IntoIter = hash_set::Iter<'a, T>;
261    fn into_iter(self) -> Self::IntoIter {
262        (&self.0).iter()
263    }
264}
265
266impl<T, S> IntoIterator for AHashSet<T, S> {
267    type Item = T;
268    type IntoIter = hash_set::IntoIter<T>;
269    fn into_iter(self) -> Self::IntoIter {
270        self.0.into_iter()
271    }
272}
273
274impl<T, S> Extend<T> for AHashSet<T, S>
275where
276    T: Eq + Hash,
277    S: BuildHasher,
278{
279    #[inline]
280    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
281        self.0.extend(iter)
282    }
283}
284
285impl<'a, T, S> Extend<&'a T> for AHashSet<T, S>
286where
287    T: 'a + Eq + Hash + Copy,
288    S: BuildHasher,
289{
290    #[inline]
291    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
292        self.0.extend(iter)
293    }
294}
295
296/// NOTE: For safety this trait impl is only available available if either of the flags `runtime-rng` (on by default) or
297/// `compile-time-rng` are enabled. This is to prevent weakly keyed maps from being accidentally created. Instead one of
298/// constructors for [RandomState] must be used.
299#[cfg(any(feature = "compile-time-rng", feature = "runtime-rng", feature = "no-rng"))]
300impl<T> Default for AHashSet<T, RandomState> {
301    /// Creates an empty `AHashSet<T, S>` with the `Default` value for the hasher.
302    #[inline]
303    fn default() -> AHashSet<T, RandomState> {
304        AHashSet(HashSet::default())
305    }
306}
307
308#[cfg(feature = "serde")]
309impl<T> Serialize for AHashSet<T>
310where
311    T: Serialize + Eq + Hash,
312{
313    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
314        self.deref().serialize(serializer)
315    }
316}
317
318#[cfg(feature = "serde")]
319impl<'de, T> Deserialize<'de> for AHashSet<T>
320where
321    T: Deserialize<'de> + Eq + Hash,
322{
323    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
324        let hash_set = HashSet::deserialize(deserializer);
325        hash_set.map(|hash_set| Self(hash_set))
326    }
327
328    fn deserialize_in_place<D: Deserializer<'de>>(deserializer: D, place: &mut Self) -> Result<(), D::Error> {
329        HashSet::deserialize_in_place(deserializer, place)
330    }
331}
332
333#[cfg(all(test, feature = "serde"))]
334mod test {
335    use super::*;
336
337    #[test]
338    fn test_serde() {
339        let mut set = AHashSet::new();
340        set.insert("for".to_string());
341        set.insert("bar".to_string());
342        let mut serialization = serde_json::to_string(&set).unwrap();
343        let mut deserialization: AHashSet<String> = serde_json::from_str(&serialization).unwrap();
344        assert_eq!(deserialization, set);
345
346        set.insert("baz".to_string());
347        serialization = serde_json::to_string(&set).unwrap();
348        let mut deserializer = serde_json::Deserializer::from_str(&serialization);
349        AHashSet::deserialize_in_place(&mut deserializer, &mut deserialization).unwrap();
350        assert_eq!(deserialization, set);
351    }
352}