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