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