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}