/rust/registry/src/index.crates.io-6f17d22bba15001f/ahash-0.8.12/src/hash_set.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use crate::RandomState; |
2 | | use std::collections::{hash_set, HashSet}; |
3 | | use std::fmt::{self, Debug}; |
4 | | use std::hash::{BuildHasher, Hash}; |
5 | | use std::iter::FromIterator; |
6 | | use std::ops::{BitAnd, BitOr, BitXor, Deref, DerefMut, Sub}; |
7 | | |
8 | | #[cfg(feature = "serde")] |
9 | | use 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)] |
17 | | pub struct AHashSet<T, S = RandomState>(HashSet<T, S>); |
18 | | |
19 | | impl<T> From<HashSet<T, RandomState>> for AHashSet<T> { |
20 | 0 | fn from(item: HashSet<T, RandomState>) -> Self { |
21 | 0 | AHashSet(item) |
22 | 0 | } |
23 | | } |
24 | | |
25 | | impl<T, const N: usize> From<[T; N]> for AHashSet<T> |
26 | | where |
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 | 0 | fn from(arr: [T; N]) -> Self { |
39 | 0 | Self::from_iter(arr) |
40 | 0 | } |
41 | | } |
42 | | |
43 | | impl<T> Into<HashSet<T, RandomState>> for AHashSet<T> { |
44 | 0 | fn into(self) -> HashSet<T, RandomState> { |
45 | 0 | self.0 |
46 | 0 | } |
47 | | } |
48 | | |
49 | | impl<T> AHashSet<T, RandomState> { |
50 | | /// This creates a hashset using [RandomState::new]. |
51 | | /// See the documentation in [RandomSource] for notes about key strength. |
52 | 0 | pub fn new() -> Self { |
53 | 0 | AHashSet(HashSet::with_hasher(RandomState::new())) |
54 | 0 | } |
55 | | |
56 | | /// This craetes a hashset with the specified capacity using [RandomState::new]. |
57 | | /// See the documentation in [RandomSource] for notes about key strength. |
58 | 0 | pub fn with_capacity(capacity: usize) -> Self { |
59 | 0 | AHashSet(HashSet::with_capacity_and_hasher(capacity, RandomState::new())) |
60 | 0 | } |
61 | | } |
62 | | |
63 | | impl<T, S> AHashSet<T, S> |
64 | | where |
65 | | S: BuildHasher, |
66 | | { |
67 | 0 | pub fn with_hasher(hash_builder: S) -> Self { |
68 | 0 | AHashSet(HashSet::with_hasher(hash_builder)) |
69 | 0 | } |
70 | | |
71 | 0 | pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { |
72 | 0 | AHashSet(HashSet::with_capacity_and_hasher(capacity, hash_builder)) |
73 | 0 | } |
74 | | } |
75 | | |
76 | | impl<T, S> Deref for AHashSet<T, S> { |
77 | | type Target = HashSet<T, S>; |
78 | 0 | fn deref(&self) -> &Self::Target { |
79 | 0 | &self.0 |
80 | 0 | } |
81 | | } |
82 | | |
83 | | impl<T, S> DerefMut for AHashSet<T, S> { |
84 | 0 | fn deref_mut(&mut self) -> &mut Self::Target { |
85 | 0 | &mut self.0 |
86 | 0 | } |
87 | | } |
88 | | |
89 | | impl<T, S> PartialEq for AHashSet<T, S> |
90 | | where |
91 | | T: Eq + Hash, |
92 | | S: BuildHasher, |
93 | | { |
94 | 0 | fn eq(&self, other: &AHashSet<T, S>) -> bool { |
95 | 0 | self.0.eq(&other.0) |
96 | 0 | } |
97 | | } |
98 | | |
99 | | impl<T, S> Eq for AHashSet<T, S> |
100 | | where |
101 | | T: Eq + Hash, |
102 | | S: BuildHasher, |
103 | | { |
104 | | } |
105 | | |
106 | | impl<T, S> BitOr<&AHashSet<T, S>> for &AHashSet<T, S> |
107 | | where |
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 | 0 | fn bitor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { |
134 | 0 | AHashSet(self.0.bitor(&rhs.0)) |
135 | 0 | } |
136 | | } |
137 | | |
138 | | impl<T, S> BitAnd<&AHashSet<T, S>> for &AHashSet<T, S> |
139 | | where |
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 | 0 | fn bitand(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { |
166 | 0 | AHashSet(self.0.bitand(&rhs.0)) |
167 | 0 | } |
168 | | } |
169 | | |
170 | | impl<T, S> BitXor<&AHashSet<T, S>> for &AHashSet<T, S> |
171 | | where |
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 | 0 | fn bitxor(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { |
198 | 0 | AHashSet(self.0.bitxor(&rhs.0)) |
199 | 0 | } |
200 | | } |
201 | | |
202 | | impl<T, S> Sub<&AHashSet<T, S>> for &AHashSet<T, S> |
203 | | where |
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 | 0 | fn sub(self, rhs: &AHashSet<T, S>) -> AHashSet<T, S> { |
230 | 0 | AHashSet(self.0.sub(&rhs.0)) |
231 | 0 | } |
232 | | } |
233 | | |
234 | | impl<T, S> Debug for AHashSet<T, S> |
235 | | where |
236 | | T: Debug, |
237 | | S: BuildHasher, |
238 | | { |
239 | 0 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
240 | 0 | self.0.fmt(fmt) |
241 | 0 | } |
242 | | } |
243 | | |
244 | | impl<T> FromIterator<T> for AHashSet<T, RandomState> |
245 | | where |
246 | | T: Eq + Hash, |
247 | | { |
248 | | /// This creates a hashset from the provided iterator using [RandomState::new]. |
249 | | /// See the documentation in [RandomSource] for notes about key strength. |
250 | | #[inline] |
251 | 0 | fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> AHashSet<T> { |
252 | 0 | let mut inner = HashSet::with_hasher(RandomState::new()); |
253 | 0 | inner.extend(iter); |
254 | 0 | AHashSet(inner) |
255 | 0 | } |
256 | | } |
257 | | |
258 | | impl<'a, T, S> IntoIterator for &'a AHashSet<T, S> { |
259 | | type Item = &'a T; |
260 | | type IntoIter = hash_set::Iter<'a, T>; |
261 | 0 | fn into_iter(self) -> Self::IntoIter { |
262 | 0 | (&self.0).iter() |
263 | 0 | } |
264 | | } |
265 | | |
266 | | impl<T, S> IntoIterator for AHashSet<T, S> { |
267 | | type Item = T; |
268 | | type IntoIter = hash_set::IntoIter<T>; |
269 | 0 | fn into_iter(self) -> Self::IntoIter { |
270 | 0 | self.0.into_iter() |
271 | 0 | } |
272 | | } |
273 | | |
274 | | impl<T, S> Extend<T> for AHashSet<T, S> |
275 | | where |
276 | | T: Eq + Hash, |
277 | | S: BuildHasher, |
278 | | { |
279 | | #[inline] |
280 | 0 | fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { |
281 | 0 | self.0.extend(iter) |
282 | 0 | } |
283 | | } |
284 | | |
285 | | impl<'a, T, S> Extend<&'a T> for AHashSet<T, S> |
286 | | where |
287 | | T: 'a + Eq + Hash + Copy, |
288 | | S: BuildHasher, |
289 | | { |
290 | | #[inline] |
291 | 0 | fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { |
292 | 0 | self.0.extend(iter) |
293 | 0 | } |
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"))] |
300 | | impl<T> Default for AHashSet<T, RandomState> { |
301 | | /// Creates an empty `AHashSet<T, S>` with the `Default` value for the hasher. |
302 | | #[inline] |
303 | 0 | fn default() -> AHashSet<T, RandomState> { |
304 | 0 | AHashSet(HashSet::default()) |
305 | 0 | } |
306 | | } |
307 | | |
308 | | #[cfg(feature = "serde")] |
309 | | impl<T> Serialize for AHashSet<T> |
310 | | where |
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")] |
319 | | impl<'de, T> Deserialize<'de> for AHashSet<T> |
320 | | where |
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"))] |
334 | | mod 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 | | } |