bevy_platform/collections/hash_set.rs
1//! Provides [`HashSet`] based on [hashbrown]'s implementation.
2//! Unlike [`hashbrown::HashSet`], [`HashSet`] defaults to [`FixedHasher`]
3//! instead of [`RandomState`](crate::hash::RandomState).
4//! This provides determinism by default with an acceptable compromise to denial
5//! of service resistance in the context of a game engine.
6
7use core::{
8 fmt::Debug,
9 hash::{BuildHasher, Hash},
10 ops::{
11 BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, DerefMut, Sub,
12 SubAssign,
13 },
14};
15
16use hashbrown::{hash_set as hb, Equivalent};
17
18use crate::hash::FixedHasher;
19
20#[cfg(feature = "rayon")]
21use rayon::prelude::{FromParallelIterator, IntoParallelIterator, ParallelExtend};
22
23// Re-exports to match `std::collections::hash_set`
24pub use hb::{Difference, Drain, Intersection, IntoIter, Iter, SymmetricDifference, Union};
25
26// Additional items from `hashbrown`
27pub use hb::{ExtractIf, OccupiedEntry, VacantEntry};
28
29/// Shortcut for [`Entry`](hb::Entry) with [`FixedHasher`] as the default hashing provider.
30pub type Entry<'a, T, S = FixedHasher> = hb::Entry<'a, T, S>;
31
32/// New-type for [`HashSet`](hb::HashSet) with [`FixedHasher`] as the default hashing provider.
33/// Can be trivially converted to and from a [hashbrown] [`HashSet`](hb::HashSet) using [`From`].
34///
35/// A new-type is used instead of a type alias due to critical methods like [`new`](hb::HashSet::new)
36/// being incompatible with Bevy's choice of default hasher.
37///
38/// Unlike [`hashbrown::HashSet`], [`HashSet`] defaults to [`FixedHasher`]
39/// instead of [`RandomState`](crate::hash::RandomState).
40/// This provides determinism by default with an acceptable compromise to denial
41/// of service resistance in the context of a game engine.
42#[repr(transparent)]
43pub struct HashSet<T, S = FixedHasher>(hb::HashSet<T, S>);
44
45impl<T, S> Clone for HashSet<T, S>
46where
47 hb::HashSet<T, S>: Clone,
48{
49 #[inline]
50 fn clone(&self) -> Self {
51 Self(self.0.clone())
52 }
53
54 #[inline]
55 fn clone_from(&mut self, source: &Self) {
56 self.0.clone_from(&source.0);
57 }
58}
59
60impl<T, S> Debug for HashSet<T, S>
61where
62 hb::HashSet<T, S>: Debug,
63{
64 #[inline]
65 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
66 <hb::HashSet<T, S> as Debug>::fmt(&self.0, f)
67 }
68}
69
70impl<T, S> Default for HashSet<T, S>
71where
72 hb::HashSet<T, S>: Default,
73{
74 #[inline]
75 fn default() -> Self {
76 Self(Default::default())
77 }
78}
79
80impl<T, S> PartialEq for HashSet<T, S>
81where
82 hb::HashSet<T, S>: PartialEq,
83{
84 #[inline]
85 fn eq(&self, other: &Self) -> bool {
86 self.0.eq(&other.0)
87 }
88}
89
90impl<T, S> Eq for HashSet<T, S> where hb::HashSet<T, S>: Eq {}
91
92impl<T, S, X> FromIterator<X> for HashSet<T, S>
93where
94 hb::HashSet<T, S>: FromIterator<X>,
95{
96 #[inline]
97 fn from_iter<U: IntoIterator<Item = X>>(iter: U) -> Self {
98 Self(FromIterator::from_iter(iter))
99 }
100}
101
102impl<T, S> IntoIterator for HashSet<T, S>
103where
104 hb::HashSet<T, S>: IntoIterator,
105{
106 type Item = <hb::HashSet<T, S> as IntoIterator>::Item;
107
108 type IntoIter = <hb::HashSet<T, S> as IntoIterator>::IntoIter;
109
110 #[inline]
111 fn into_iter(self) -> Self::IntoIter {
112 self.0.into_iter()
113 }
114}
115
116impl<'a, T, S> IntoIterator for &'a HashSet<T, S>
117where
118 &'a hb::HashSet<T, S>: IntoIterator,
119{
120 type Item = <&'a hb::HashSet<T, S> as IntoIterator>::Item;
121
122 type IntoIter = <&'a hb::HashSet<T, S> as IntoIterator>::IntoIter;
123
124 #[inline]
125 fn into_iter(self) -> Self::IntoIter {
126 (&self.0).into_iter()
127 }
128}
129
130impl<'a, T, S> IntoIterator for &'a mut HashSet<T, S>
131where
132 &'a mut hb::HashSet<T, S>: IntoIterator,
133{
134 type Item = <&'a mut hb::HashSet<T, S> as IntoIterator>::Item;
135
136 type IntoIter = <&'a mut hb::HashSet<T, S> as IntoIterator>::IntoIter;
137
138 #[inline]
139 fn into_iter(self) -> Self::IntoIter {
140 (&mut self.0).into_iter()
141 }
142}
143
144impl<T, S, X> Extend<X> for HashSet<T, S>
145where
146 hb::HashSet<T, S>: Extend<X>,
147{
148 #[inline]
149 fn extend<U: IntoIterator<Item = X>>(&mut self, iter: U) {
150 self.0.extend(iter);
151 }
152}
153
154impl<T, const N: usize> From<[T; N]> for HashSet<T, FixedHasher>
155where
156 T: Eq + Hash,
157{
158 fn from(value: [T; N]) -> Self {
159 value.into_iter().collect()
160 }
161}
162
163impl<T, S> From<crate::collections::HashMap<T, (), S>> for HashSet<T, S> {
164 #[inline]
165 fn from(value: crate::collections::HashMap<T, (), S>) -> Self {
166 Self(hb::HashSet::from(hashbrown::HashMap::from(value)))
167 }
168}
169
170impl<T, S> From<hb::HashSet<T, S>> for HashSet<T, S> {
171 #[inline]
172 fn from(value: hb::HashSet<T, S>) -> Self {
173 Self(value)
174 }
175}
176
177impl<T, S> From<HashSet<T, S>> for hb::HashSet<T, S> {
178 #[inline]
179 fn from(value: HashSet<T, S>) -> Self {
180 value.0
181 }
182}
183
184impl<T, S> Deref for HashSet<T, S> {
185 type Target = hb::HashSet<T, S>;
186
187 #[inline]
188 fn deref(&self) -> &Self::Target {
189 &self.0
190 }
191}
192
193impl<T, S> DerefMut for HashSet<T, S> {
194 #[inline]
195 fn deref_mut(&mut self) -> &mut Self::Target {
196 &mut self.0
197 }
198}
199
200#[cfg(feature = "serialize")]
201impl<T, S> serde::Serialize for HashSet<T, S>
202where
203 hb::HashSet<T, S>: serde::Serialize,
204{
205 #[inline]
206 fn serialize<U>(&self, serializer: U) -> Result<U::Ok, U::Error>
207 where
208 U: serde::Serializer,
209 {
210 self.0.serialize(serializer)
211 }
212}
213
214#[cfg(feature = "serialize")]
215impl<'de, T, S> serde::Deserialize<'de> for HashSet<T, S>
216where
217 hb::HashSet<T, S>: serde::Deserialize<'de>,
218{
219 #[inline]
220 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
221 where
222 D: serde::Deserializer<'de>,
223 {
224 Ok(Self(serde::Deserialize::deserialize(deserializer)?))
225 }
226}
227
228#[cfg(feature = "rayon")]
229impl<T, S, U> FromParallelIterator<U> for HashSet<T, S>
230where
231 hb::HashSet<T, S>: FromParallelIterator<U>,
232 U: Send,
233{
234 fn from_par_iter<P>(par_iter: P) -> Self
235 where
236 P: IntoParallelIterator<Item = U>,
237 {
238 Self(<hb::HashSet<T, S> as FromParallelIterator<U>>::from_par_iter(par_iter))
239 }
240}
241
242#[cfg(feature = "rayon")]
243impl<T, S> IntoParallelIterator for HashSet<T, S>
244where
245 hb::HashSet<T, S>: IntoParallelIterator,
246{
247 type Item = <hb::HashSet<T, S> as IntoParallelIterator>::Item;
248 type Iter = <hb::HashSet<T, S> as IntoParallelIterator>::Iter;
249
250 fn into_par_iter(self) -> Self::Iter {
251 self.0.into_par_iter()
252 }
253}
254
255#[cfg(feature = "rayon")]
256impl<'a, T: Sync, S> IntoParallelIterator for &'a HashSet<T, S>
257where
258 &'a hb::HashSet<T, S>: IntoParallelIterator,
259{
260 type Item = <&'a hb::HashSet<T, S> as IntoParallelIterator>::Item;
261 type Iter = <&'a hb::HashSet<T, S> as IntoParallelIterator>::Iter;
262
263 fn into_par_iter(self) -> Self::Iter {
264 (&self.0).into_par_iter()
265 }
266}
267
268#[cfg(feature = "rayon")]
269impl<T, S, U> ParallelExtend<U> for HashSet<T, S>
270where
271 hb::HashSet<T, S>: ParallelExtend<U>,
272 U: Send,
273{
274 fn par_extend<I>(&mut self, par_iter: I)
275 where
276 I: IntoParallelIterator<Item = U>,
277 {
278 <hb::HashSet<T, S> as ParallelExtend<U>>::par_extend(&mut self.0, par_iter);
279 }
280}
281
282impl<T> HashSet<T, FixedHasher> {
283 /// Creates an empty [`HashSet`].
284 ///
285 /// Refer to [`new`](hb::HashSet::new) for further details.
286 ///
287 /// # Examples
288 ///
289 /// ```rust
290 /// # use bevy_platform::collections::HashSet;
291 /// #
292 /// // Creates a HashSet with zero capacity.
293 /// let map = HashSet::new();
294 /// #
295 /// # let mut map = map;
296 /// # map.insert("foo");
297 /// # assert_eq!(map.get("foo"), Some("foo").as_ref());
298 /// ```
299 #[inline]
300 pub const fn new() -> Self {
301 Self::with_hasher(FixedHasher)
302 }
303
304 /// Creates an empty [`HashSet`] with the specified capacity.
305 ///
306 /// Refer to [`with_capacity`](hb::HashSet::with_capacity) for further details.
307 ///
308 /// # Examples
309 ///
310 /// ```rust
311 /// # use bevy_platform::collections::HashSet;
312 /// #
313 /// // Creates a HashSet with capacity for at least 5 entries.
314 /// let map = HashSet::with_capacity(5);
315 /// #
316 /// # let mut map = map;
317 /// # map.insert("foo");
318 /// # assert_eq!(map.get("foo"), Some("foo").as_ref());
319 /// ```
320 #[inline]
321 pub fn with_capacity(capacity: usize) -> Self {
322 Self::with_capacity_and_hasher(capacity, FixedHasher)
323 }
324}
325
326impl<T, S> HashSet<T, S> {
327 /// Returns the number of elements the set can hold without reallocating.
328 ///
329 /// Refer to [`capacity`](hb::HashSet::capacity) for further details.
330 ///
331 /// # Examples
332 ///
333 /// ```rust
334 /// # use bevy_platform::collections::HashSet;
335 /// let map = HashSet::with_capacity(5);
336 ///
337 /// # let map: HashSet<()> = map;
338 /// #
339 /// assert!(map.capacity() >= 5);
340 /// ```
341 #[inline]
342 pub fn capacity(&self) -> usize {
343 self.0.capacity()
344 }
345
346 /// An iterator visiting all elements in arbitrary order.
347 /// The iterator element type is `&'a T`.
348 ///
349 /// Refer to [`iter`](hb::HashSet::iter) for further details.
350 ///
351 /// # Examples
352 ///
353 /// ```rust
354 /// # use bevy_platform::collections::HashSet;
355 /// #
356 /// let mut map = HashSet::new();
357 ///
358 /// map.insert("foo");
359 /// map.insert("bar");
360 /// map.insert("baz");
361 ///
362 /// for value in map.iter() {
363 /// // "foo", "bar", "baz"
364 /// // Note that the above order is not guaranteed
365 /// }
366 /// #
367 /// # assert_eq!(map.iter().count(), 3);
368 /// ```
369 #[inline]
370 pub fn iter(&self) -> Iter<'_, T> {
371 self.0.iter()
372 }
373
374 /// Returns the number of elements in the set.
375 ///
376 /// Refer to [`len`](hb::HashSet::len) for further details.
377 ///
378 /// # Examples
379 ///
380 /// ```rust
381 /// # use bevy_platform::collections::HashSet;
382 /// let mut map = HashSet::new();
383 ///
384 /// assert_eq!(map.len(), 0);
385 ///
386 /// map.insert("foo");
387 ///
388 /// assert_eq!(map.len(), 1);
389 /// ```
390 #[inline]
391 pub fn len(&self) -> usize {
392 self.0.len()
393 }
394
395 /// Returns `true` if the set contains no elements.
396 ///
397 /// Refer to [`is_empty`](hb::HashSet::is_empty) for further details.
398 ///
399 /// # Examples
400 ///
401 /// ```rust
402 /// # use bevy_platform::collections::HashSet;
403 /// let mut map = HashSet::new();
404 ///
405 /// assert!(map.is_empty());
406 ///
407 /// map.insert("foo");
408 ///
409 /// assert!(!map.is_empty());
410 /// ```
411 #[inline]
412 pub fn is_empty(&self) -> bool {
413 self.0.is_empty()
414 }
415
416 /// Clears the set, returning all elements in an iterator.
417 ///
418 /// Refer to [`drain`](hb::HashSet::drain) for further details.
419 ///
420 /// # Examples
421 ///
422 /// ```rust
423 /// # use bevy_platform::collections::HashSet;
424 /// #
425 /// let mut map = HashSet::new();
426 ///
427 /// map.insert("foo");
428 /// map.insert("bar");
429 /// map.insert("baz");
430 ///
431 /// for value in map.drain() {
432 /// // "foo", "bar", "baz"
433 /// // Note that the above order is not guaranteed
434 /// }
435 ///
436 /// assert!(map.is_empty());
437 /// ```
438 #[inline]
439 pub fn drain(&mut self) -> Drain<'_, T> {
440 self.0.drain()
441 }
442
443 /// Retains only the elements specified by the predicate.
444 ///
445 /// Refer to [`retain`](hb::HashSet::retain) for further details.
446 ///
447 /// # Examples
448 ///
449 /// ```rust
450 /// # use bevy_platform::collections::HashSet;
451 /// #
452 /// let mut map = HashSet::new();
453 ///
454 /// map.insert("foo");
455 /// map.insert("bar");
456 /// map.insert("baz");
457 ///
458 /// map.retain(|value| *value == "baz");
459 ///
460 /// assert_eq!(map.len(), 1);
461 /// ```
462 #[inline]
463 pub fn retain<F>(&mut self, f: F)
464 where
465 F: FnMut(&T) -> bool,
466 {
467 self.0.retain(f);
468 }
469
470 /// Drains elements which are true under the given predicate,
471 /// and returns an iterator over the removed items.
472 ///
473 /// Refer to [`extract_if`](hb::HashSet::extract_if) for further details.
474 ///
475 /// # Examples
476 ///
477 /// ```rust
478 /// # use bevy_platform::collections::HashSet;
479 /// #
480 /// let mut map = HashSet::new();
481 ///
482 /// map.insert("foo");
483 /// map.insert("bar");
484 /// map.insert("baz");
485 ///
486 /// let extracted = map
487 /// .extract_if(|value| *value == "baz")
488 /// .collect::<Vec<_>>();
489 ///
490 /// assert_eq!(map.len(), 2);
491 /// assert_eq!(extracted.len(), 1);
492 /// ```
493 #[inline]
494 pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, T, F>
495 where
496 F: FnMut(&T) -> bool,
497 {
498 self.0.extract_if(f)
499 }
500
501 /// Clears the set, removing all values.
502 ///
503 /// Refer to [`clear`](hb::HashSet::clear) for further details.
504 ///
505 /// # Examples
506 ///
507 /// ```rust
508 /// # use bevy_platform::collections::HashSet;
509 /// #
510 /// let mut map = HashSet::new();
511 ///
512 /// map.insert("foo");
513 /// map.insert("bar");
514 /// map.insert("baz");
515 ///
516 /// map.clear();
517 ///
518 /// assert!(map.is_empty());
519 /// ```
520 #[inline]
521 pub fn clear(&mut self) {
522 self.0.clear();
523 }
524
525 /// Creates a new empty hash set which will use the given hasher to hash
526 /// keys.
527 ///
528 /// Refer to [`with_hasher`](hb::HashSet::with_hasher) for further details.
529 ///
530 /// # Examples
531 ///
532 /// ```rust
533 /// # use bevy_platform::collections::HashSet;
534 /// # use bevy_platform::hash::FixedHasher as SomeHasher;
535 /// // Creates a HashSet with the provided hasher.
536 /// let map = HashSet::with_hasher(SomeHasher);
537 /// #
538 /// # let mut map = map;
539 /// # map.insert("foo");
540 /// # assert_eq!(map.get("foo"), Some("foo").as_ref());
541 /// ```
542 #[inline]
543 pub const fn with_hasher(hasher: S) -> Self {
544 Self(hb::HashSet::with_hasher(hasher))
545 }
546
547 /// Creates an empty [`HashSet`] with the specified capacity, using
548 /// `hasher` to hash the keys.
549 ///
550 /// Refer to [`with_capacity_and_hasher`](hb::HashSet::with_capacity_and_hasher) for further details.
551 ///
552 /// # Examples
553 ///
554 /// ```rust
555 /// # use bevy_platform::collections::HashSet;
556 /// # use bevy_platform::hash::FixedHasher as SomeHasher;
557 /// // Creates a HashSet with capacity for 5 entries and the provided hasher.
558 /// let map = HashSet::with_capacity_and_hasher(5, SomeHasher);
559 /// #
560 /// # let mut map = map;
561 /// # map.insert("foo");
562 /// # assert_eq!(map.get("foo"), Some("foo").as_ref());
563 /// ```
564 #[inline]
565 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
566 Self(hb::HashSet::with_capacity_and_hasher(capacity, hasher))
567 }
568
569 /// Returns a reference to the set's [`BuildHasher`].
570 ///
571 /// Refer to [`hasher`](hb::HashSet::hasher) for further details.
572 #[inline]
573 pub fn hasher(&self) -> &S {
574 self.0.hasher()
575 }
576
577 /// Takes the inner [`HashSet`](hb::HashSet) out of this wrapper.
578 ///
579 /// # Examples
580 ///
581 /// ```rust
582 /// # use bevy_platform::collections::HashSet;
583 /// let map: HashSet<&'static str> = HashSet::new();
584 /// let map: hashbrown::HashSet<&'static str, _> = map.into_inner();
585 /// ```
586 #[inline]
587 pub fn into_inner(self) -> hb::HashSet<T, S> {
588 self.0
589 }
590}
591
592impl<T, S> HashSet<T, S>
593where
594 T: Eq + Hash,
595 S: BuildHasher,
596{
597 /// Reserves capacity for at least `additional` more elements to be inserted
598 /// in the [`HashSet`]. The collection may reserve more space to avoid
599 /// frequent reallocations.
600 ///
601 /// Refer to [`reserve`](hb::HashSet::reserve) for further details.
602 ///
603 /// # Examples
604 ///
605 /// ```rust
606 /// # use bevy_platform::collections::HashSet;
607 /// let mut map = HashSet::with_capacity(5);
608 ///
609 /// # let mut map: HashSet<()> = map;
610 /// #
611 /// assert!(map.capacity() >= 5);
612 ///
613 /// map.reserve(10);
614 ///
615 /// assert!(map.capacity() - map.len() >= 10);
616 /// ```
617 #[inline]
618 pub fn reserve(&mut self, additional: usize) {
619 self.0.reserve(additional);
620 }
621
622 /// Tries to reserve capacity for at least `additional` more elements to be inserted
623 /// in the given `HashSet<K,V>`. The collection may reserve more space to avoid
624 /// frequent reallocations.
625 ///
626 /// Refer to [`try_reserve`](hb::HashSet::try_reserve) for further details.
627 ///
628 /// # Examples
629 ///
630 /// ```rust
631 /// # use bevy_platform::collections::HashSet;
632 /// let mut map = HashSet::with_capacity(5);
633 ///
634 /// # let mut map: HashSet<()> = map;
635 /// #
636 /// assert!(map.capacity() >= 5);
637 ///
638 /// map.try_reserve(10).expect("Out of Memory!");
639 ///
640 /// assert!(map.capacity() - map.len() >= 10);
641 /// ```
642 #[inline]
643 pub fn try_reserve(&mut self, additional: usize) -> Result<(), hashbrown::TryReserveError> {
644 self.0.try_reserve(additional)
645 }
646
647 /// Shrinks the capacity of the set as much as possible. It will drop
648 /// down as much as possible while maintaining the internal rules
649 /// and possibly leaving some space in accordance with the resize policy.
650 ///
651 /// Refer to [`shrink_to_fit`](hb::HashSet::shrink_to_fit) for further details.
652 ///
653 /// # Examples
654 ///
655 /// ```rust
656 /// # use bevy_platform::collections::HashSet;
657 /// let mut map = HashSet::with_capacity(5);
658 ///
659 /// map.insert("foo");
660 /// map.insert("bar");
661 /// map.insert("baz");
662 ///
663 /// assert!(map.capacity() >= 5);
664 ///
665 /// map.shrink_to_fit();
666 ///
667 /// assert_eq!(map.capacity(), 3);
668 /// ```
669 #[inline]
670 pub fn shrink_to_fit(&mut self) {
671 self.0.shrink_to_fit();
672 }
673
674 /// Shrinks the capacity of the set with a lower limit. It will drop
675 /// down no lower than the supplied limit while maintaining the internal rules
676 /// and possibly leaving some space in accordance with the resize policy.
677 ///
678 /// Refer to [`shrink_to`](hb::HashSet::shrink_to) for further details.
679 #[inline]
680 pub fn shrink_to(&mut self, min_capacity: usize) {
681 self.0.shrink_to(min_capacity);
682 }
683
684 /// Visits the values representing the difference,
685 /// i.e., the values that are in `self` but not in `other`.
686 ///
687 /// Refer to [`difference`](hb::HashSet::difference) for further details.
688 #[inline]
689 pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, S> {
690 self.0.difference(other)
691 }
692
693 /// Visits the values representing the symmetric difference,
694 /// i.e., the values that are in `self` or in `other` but not in both.
695 ///
696 /// Refer to [`symmetric_difference`](hb::HashSet::symmetric_difference) for further details.
697 #[inline]
698 pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, S> {
699 self.0.symmetric_difference(other)
700 }
701
702 /// Visits the values representing the intersection,
703 /// i.e., the values that are both in `self` and `other`.
704 ///
705 /// Refer to [`intersection`](hb::HashSet::intersection) for further details.
706 #[inline]
707 pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, S> {
708 self.0.intersection(other)
709 }
710
711 /// Visits the values representing the union,
712 /// i.e., all the values in `self` or `other`, without duplicates.
713 ///
714 /// Refer to [`union`](hb::HashSet::union) for further details.
715 #[inline]
716 pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, S> {
717 self.0.union(other)
718 }
719
720 /// Returns `true` if the set contains a value.
721 ///
722 /// Refer to [`contains`](hb::HashSet::contains) for further details.
723 ///
724 /// # Examples
725 ///
726 /// ```rust
727 /// # use bevy_platform::collections::HashSet;
728 /// let mut map = HashSet::new();
729 ///
730 /// map.insert("foo");
731 ///
732 /// assert!(map.contains("foo"));
733 /// ```
734 #[inline]
735 pub fn contains<Q>(&self, value: &Q) -> bool
736 where
737 Q: Hash + Equivalent<T> + ?Sized,
738 {
739 self.0.contains(value)
740 }
741
742 /// Returns a reference to the value in the set, if any, that is equal to the given value.
743 ///
744 /// Refer to [`get`](hb::HashSet::get) for further details.
745 ///
746 /// # Examples
747 ///
748 /// ```rust
749 /// # use bevy_platform::collections::HashSet;
750 /// let mut map = HashSet::new();
751 ///
752 /// map.insert("foo");
753 ///
754 /// assert_eq!(map.get("foo"), Some(&"foo"));
755 /// ```
756 #[inline]
757 pub fn get<Q>(&self, value: &Q) -> Option<&T>
758 where
759 Q: Hash + Equivalent<T> + ?Sized,
760 {
761 self.0.get(value)
762 }
763
764 /// Inserts the given `value` into the set if it is not present, then
765 /// returns a reference to the value in the set.
766 ///
767 /// Refer to [`get_or_insert`](hb::HashSet::get_or_insert) for further details.
768 ///
769 /// # Examples
770 ///
771 /// ```rust
772 /// # use bevy_platform::collections::HashSet;
773 /// let mut map = HashSet::new();
774 ///
775 /// assert_eq!(map.get_or_insert("foo"), &"foo");
776 /// ```
777 #[inline]
778 pub fn get_or_insert(&mut self, value: T) -> &T {
779 self.0.get_or_insert(value)
780 }
781
782 /// Inserts a value computed from `f` into the set if the given `value` is
783 /// not present, then returns a reference to the value in the set.
784 ///
785 /// Refer to [`get_or_insert_with`](hb::HashSet::get_or_insert_with) for further details.
786 ///
787 /// # Examples
788 ///
789 /// ```rust
790 /// # use bevy_platform::collections::HashSet;
791 /// let mut map = HashSet::new();
792 ///
793 /// assert_eq!(map.get_or_insert_with(&"foo", |_| "foo"), &"foo");
794 /// ```
795 #[inline]
796 pub fn get_or_insert_with<Q, F>(&mut self, value: &Q, f: F) -> &T
797 where
798 Q: Hash + Equivalent<T> + ?Sized,
799 F: FnOnce(&Q) -> T,
800 {
801 self.0.get_or_insert_with(value, f)
802 }
803
804 /// Gets the given value's corresponding entry in the set for in-place manipulation.
805 ///
806 /// Refer to [`entry`](hb::HashSet::entry) for further details.
807 ///
808 /// # Examples
809 ///
810 /// ```rust
811 /// # use bevy_platform::collections::HashSet;
812 /// let mut map = HashSet::new();
813 ///
814 /// let value = map.entry("foo").or_insert();
815 /// #
816 /// # assert_eq!(value, ());
817 /// ```
818 #[inline]
819 pub fn entry(&mut self, value: T) -> Entry<'_, T, S> {
820 self.0.entry(value)
821 }
822
823 /// Returns `true` if `self` has no elements in common with `other`.
824 /// This is equivalent to checking for an empty intersection.
825 ///
826 /// Refer to [`is_disjoint`](hb::HashSet::is_disjoint) for further details.
827 #[inline]
828 pub fn is_disjoint(&self, other: &Self) -> bool {
829 self.0.is_disjoint(other)
830 }
831
832 /// Returns `true` if the set is a subset of another,
833 /// i.e., `other` contains at least all the values in `self`.
834 ///
835 /// Refer to [`is_subset`](hb::HashSet::is_subset) for further details.
836 #[inline]
837 pub fn is_subset(&self, other: &Self) -> bool {
838 self.0.is_subset(other)
839 }
840
841 /// Returns `true` if the set is a superset of another,
842 /// i.e., `self` contains at least all the values in `other`.
843 ///
844 /// Refer to [`is_superset`](hb::HashSet::is_superset) for further details.
845 #[inline]
846 pub fn is_superset(&self, other: &Self) -> bool {
847 self.0.is_superset(other)
848 }
849
850 /// Adds a value to the set.
851 ///
852 /// Refer to [`insert`](hb::HashSet::insert) for further details.
853 ///
854 /// # Examples
855 ///
856 /// ```rust
857 /// # use bevy_platform::collections::HashSet;
858 /// let mut map = HashSet::new();
859 ///
860 /// map.insert("foo");
861 ///
862 /// assert!(map.contains("foo"));
863 /// ```
864 #[inline]
865 pub fn insert(&mut self, value: T) -> bool {
866 self.0.insert(value)
867 }
868
869 /// Adds a value to the set, replacing the existing value, if any, that is equal to the given
870 /// one. Returns the replaced value.
871 ///
872 /// Refer to [`replace`](hb::HashSet::replace) for further details.
873 ///
874 /// # Examples
875 ///
876 /// ```rust
877 /// # use bevy_platform::collections::HashSet;
878 /// let mut map = HashSet::new();
879 ///
880 /// map.insert("foo");
881 ///
882 /// assert_eq!(map.replace("foo"), Some("foo"));
883 /// ```
884 #[inline]
885 pub fn replace(&mut self, value: T) -> Option<T> {
886 self.0.replace(value)
887 }
888
889 /// Removes a value from the set. Returns whether the value was
890 /// present in the set.
891 ///
892 /// Refer to [`remove`](hb::HashSet::remove) for further details.
893 ///
894 /// # Examples
895 ///
896 /// ```rust
897 /// # use bevy_platform::collections::HashSet;
898 /// let mut map = HashSet::new();
899 ///
900 /// map.insert("foo");
901 ///
902 /// assert!(map.remove("foo"));
903 ///
904 /// assert!(map.is_empty());
905 /// ```
906 #[inline]
907 pub fn remove<Q>(&mut self, value: &Q) -> bool
908 where
909 Q: Hash + Equivalent<T> + ?Sized,
910 {
911 self.0.remove(value)
912 }
913
914 /// Removes and returns the value in the set, if any, that is equal to the given one.
915 ///
916 /// Refer to [`take`](hb::HashSet::take) for further details.
917 ///
918 /// # Examples
919 ///
920 /// ```rust
921 /// # use bevy_platform::collections::HashSet;
922 /// let mut map = HashSet::new();
923 ///
924 /// map.insert("foo");
925 ///
926 /// assert_eq!(map.take("foo"), Some("foo"));
927 ///
928 /// assert!(map.is_empty());
929 /// ```
930 #[inline]
931 pub fn take<Q>(&mut self, value: &Q) -> Option<T>
932 where
933 Q: Hash + Equivalent<T> + ?Sized,
934 {
935 self.0.take(value)
936 }
937
938 /// Returns the total amount of memory allocated internally by the hash
939 /// set, in bytes.
940 ///
941 /// Refer to [`allocation_size`](hb::HashSet::allocation_size) for further details.
942 ///
943 /// # Examples
944 ///
945 /// ```rust
946 /// # use bevy_platform::collections::HashSet;
947 /// let mut map = HashSet::new();
948 ///
949 /// assert_eq!(map.allocation_size(), 0);
950 ///
951 /// map.insert("foo");
952 ///
953 /// assert!(map.allocation_size() >= size_of::<&'static str>());
954 /// ```
955 #[inline]
956 pub fn allocation_size(&self) -> usize {
957 self.0.allocation_size()
958 }
959
960 /// Insert a value the set without checking if the value already exists in the set.
961 ///
962 /// Refer to [`insert_unique_unchecked`](hb::HashSet::insert_unique_unchecked) for further details.
963 ///
964 /// # Safety
965 ///
966 /// This operation is safe if a value does not exist in the set.
967 ///
968 /// However, if a value exists in the set already, the behavior is unspecified:
969 /// this operation may panic, loop forever, or any following operation with the set
970 /// may panic, loop forever or return arbitrary result.
971 ///
972 /// That said, this operation (and following operations) are guaranteed to
973 /// not violate memory safety.
974 ///
975 /// However this operation is still unsafe because the resulting `HashSet`
976 /// may be passed to unsafe code which does expect the set to behave
977 /// correctly, and would cause unsoundness as a result.
978 #[expect(
979 unsafe_code,
980 reason = "re-exporting unsafe method from Hashbrown requires unsafe code"
981 )]
982 #[inline]
983 pub unsafe fn insert_unique_unchecked(&mut self, value: T) -> &T {
984 // SAFETY: safety contract is ensured by the caller.
985 unsafe { self.0.insert_unique_unchecked(value) }
986 }
987}
988
989impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>
990where
991 for<'a> &'a hb::HashSet<T, S>: BitOr<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,
992{
993 type Output = HashSet<T, S>;
994
995 /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`.
996 #[inline]
997 fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
998 HashSet(self.0.bitor(&rhs.0))
999 }
1000}
1001
1002impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>
1003where
1004 for<'a> &'a hb::HashSet<T, S>: BitAnd<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,
1005{
1006 type Output = HashSet<T, S>;
1007
1008 /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`.
1009 #[inline]
1010 fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1011 HashSet(self.0.bitand(&rhs.0))
1012 }
1013}
1014
1015impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>
1016where
1017 for<'a> &'a hb::HashSet<T, S>: BitXor<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,
1018{
1019 type Output = HashSet<T, S>;
1020
1021 /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`.
1022 #[inline]
1023 fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1024 HashSet(self.0.bitxor(&rhs.0))
1025 }
1026}
1027
1028impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>
1029where
1030 for<'a> &'a hb::HashSet<T, S>: Sub<&'a hb::HashSet<T, S>, Output = hb::HashSet<T, S>>,
1031{
1032 type Output = HashSet<T, S>;
1033
1034 /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`.
1035 #[inline]
1036 fn sub(self, rhs: &HashSet<T, S>) -> HashSet<T, S> {
1037 HashSet(self.0.sub(&rhs.0))
1038 }
1039}
1040
1041impl<T, S> BitOrAssign<&HashSet<T, S>> for HashSet<T, S>
1042where
1043 hb::HashSet<T, S>: for<'a> BitOrAssign<&'a hb::HashSet<T, S>>,
1044{
1045 /// Modifies this set to contain the union of `self` and `rhs`.
1046 #[inline]
1047 fn bitor_assign(&mut self, rhs: &HashSet<T, S>) {
1048 self.0.bitor_assign(&rhs.0);
1049 }
1050}
1051
1052impl<T, S> BitAndAssign<&HashSet<T, S>> for HashSet<T, S>
1053where
1054 hb::HashSet<T, S>: for<'a> BitAndAssign<&'a hb::HashSet<T, S>>,
1055{
1056 /// Modifies this set to contain the intersection of `self` and `rhs`.
1057 #[inline]
1058 fn bitand_assign(&mut self, rhs: &HashSet<T, S>) {
1059 self.0.bitand_assign(&rhs.0);
1060 }
1061}
1062
1063impl<T, S> BitXorAssign<&HashSet<T, S>> for HashSet<T, S>
1064where
1065 hb::HashSet<T, S>: for<'a> BitXorAssign<&'a hb::HashSet<T, S>>,
1066{
1067 /// Modifies this set to contain the symmetric difference of `self` and `rhs`.
1068 #[inline]
1069 fn bitxor_assign(&mut self, rhs: &HashSet<T, S>) {
1070 self.0.bitxor_assign(&rhs.0);
1071 }
1072}
1073
1074impl<T, S> SubAssign<&HashSet<T, S>> for HashSet<T, S>
1075where
1076 hb::HashSet<T, S>: for<'a> SubAssign<&'a hb::HashSet<T, S>>,
1077{
1078 /// Modifies this set to contain the difference of `self` and `rhs`.
1079 #[inline]
1080 fn sub_assign(&mut self, rhs: &HashSet<T, S>) {
1081 self.0.sub_assign(&rhs.0);
1082 }
1083}