Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_platform/src/collections/hash_set.rs
6849 views
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
7
use 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
16
use hashbrown::{hash_set as hb, Equivalent};
17
18
use crate::hash::FixedHasher;
19
20
#[cfg(feature = "rayon")]
21
use rayon::prelude::{FromParallelIterator, IntoParallelIterator, ParallelExtend};
22
23
// Re-exports to match `std::collections::hash_set`
24
pub use hb::{Difference, Drain, Intersection, IntoIter, Iter, SymmetricDifference, Union};
25
26
// Additional items from `hashbrown`
27
pub use hb::{ExtractIf, OccupiedEntry, VacantEntry};
28
29
/// Shortcut for [`Entry`](hb::Entry) with [`FixedHasher`] as the default hashing provider.
30
pub 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)]
38
pub struct HashSet<T, S = FixedHasher>(hb::HashSet<T, S>);
39
40
impl<T, S> Clone for HashSet<T, S>
41
where
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
55
impl<T, S> Debug for HashSet<T, S>
56
where
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
65
impl<T, S> Default for HashSet<T, S>
66
where
67
hb::HashSet<T, S>: Default,
68
{
69
#[inline]
70
fn default() -> Self {
71
Self(Default::default())
72
}
73
}
74
75
impl<T, S> PartialEq for HashSet<T, S>
76
where
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
85
impl<T, S> Eq for HashSet<T, S> where hb::HashSet<T, S>: Eq {}
86
87
impl<T, S, X> FromIterator<X> for HashSet<T, S>
88
where
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
97
impl<T, S> IntoIterator for HashSet<T, S>
98
where
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
111
impl<'a, T, S> IntoIterator for &'a HashSet<T, S>
112
where
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
125
impl<'a, T, S> IntoIterator for &'a mut HashSet<T, S>
126
where
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
139
impl<T, S, X> Extend<X> for HashSet<T, S>
140
where
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
149
impl<T, const N: usize> From<[T; N]> for HashSet<T, FixedHasher>
150
where
151
T: Eq + Hash,
152
{
153
fn from(value: [T; N]) -> Self {
154
value.into_iter().collect()
155
}
156
}
157
158
impl<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
165
impl<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
172
impl<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
179
impl<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
188
impl<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")]
196
impl<T, S> serde::Serialize for HashSet<T, S>
197
where
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")]
210
impl<'de, T, S> serde::Deserialize<'de> for HashSet<T, S>
211
where
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")]
224
impl<T, S, U> FromParallelIterator<U> for HashSet<T, S>
225
where
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")]
238
impl<T, S> IntoParallelIterator for HashSet<T, S>
239
where
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")]
251
impl<'a, T: Sync, S> IntoParallelIterator for &'a HashSet<T, S>
252
where
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")]
264
impl<T, S, U> ParallelExtend<U> for HashSet<T, S>
265
where
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
277
impl<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
321
impl<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
587
impl<T, S> HashSet<T, S>
588
where
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
984
impl<T, S> BitOr<&HashSet<T, S>> for &HashSet<T, S>
985
where
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
997
impl<T, S> BitAnd<&HashSet<T, S>> for &HashSet<T, S>
998
where
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
1010
impl<T, S> BitXor<&HashSet<T, S>> for &HashSet<T, S>
1011
where
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
1023
impl<T, S> Sub<&HashSet<T, S>> for &HashSet<T, S>
1024
where
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
1036
impl<T, S> BitOrAssign<&HashSet<T, S>> for HashSet<T, S>
1037
where
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
1047
impl<T, S> BitAndAssign<&HashSet<T, S>> for HashSet<T, S>
1048
where
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
1058
impl<T, S> BitXorAssign<&HashSet<T, S>> for HashSet<T, S>
1059
where
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
1069
impl<T, S> SubAssign<&HashSet<T, S>> for HashSet<T, S>
1070
where
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
}
1079
1080