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}