Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_platform/src/collections/hash_map.rs
9334 views
1
//! Provides [`HashMap`] based on [hashbrown]'s implementation.
2
//! Unlike [`hashbrown::HashMap`], [`HashMap`] defaults to [`FixedHasher`]
3
//! instead of [`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::{Deref, DerefMut, Index},
11
};
12
13
use hashbrown::{hash_map as hb, Equivalent};
14
15
use crate::hash::FixedHasher;
16
17
#[cfg(feature = "rayon")]
18
use rayon::prelude::{FromParallelIterator, IntoParallelIterator, ParallelExtend};
19
20
// Re-exports to match `std::collections::hash_map`
21
pub use {
22
crate::hash::{DefaultHasher, RandomState},
23
hb::{
24
Drain, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, OccupiedEntry, VacantEntry,
25
Values, ValuesMut,
26
},
27
};
28
29
// Additional items from `hashbrown`
30
pub use hb::{
31
EntryRef, ExtractIf, OccupiedError, RawEntryBuilder, RawEntryBuilderMut, RawEntryMut,
32
RawOccupiedEntryMut,
33
};
34
35
/// Shortcut for [`Entry`](hb::Entry) with [`FixedHasher`] as the default hashing provider.
36
pub type Entry<'a, K, V, S = FixedHasher> = hb::Entry<'a, K, V, S>;
37
38
/// New-type for [`HashMap`](hb::HashMap) with [`FixedHasher`] as the default hashing provider.
39
/// Can be trivially converted to and from a [hashbrown] [`HashMap`](hb::HashMap) using [`From`].
40
///
41
/// A new-type is used instead of a type alias due to critical methods like [`new`](hb::HashMap::new)
42
/// being incompatible with Bevy's choice of default hasher.
43
///
44
/// Unlike [`hashbrown::HashMap`], [`HashMap`] defaults to [`FixedHasher`]
45
/// instead of [`RandomState`].
46
/// This provides determinism by default with an acceptable compromise to denial
47
/// of service resistance in the context of a game engine.
48
#[repr(transparent)]
49
pub struct HashMap<K, V, S = FixedHasher>(hb::HashMap<K, V, S>);
50
51
impl<K, V, S> Clone for HashMap<K, V, S>
52
where
53
hb::HashMap<K, V, S>: Clone,
54
{
55
#[inline]
56
fn clone(&self) -> Self {
57
Self(self.0.clone())
58
}
59
60
#[inline]
61
fn clone_from(&mut self, source: &Self) {
62
self.0.clone_from(&source.0);
63
}
64
}
65
66
impl<K, V, S> Debug for HashMap<K, V, S>
67
where
68
hb::HashMap<K, V, S>: Debug,
69
{
70
#[inline]
71
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
72
<hb::HashMap<K, V, S> as Debug>::fmt(&self.0, f)
73
}
74
}
75
76
impl<K, V, S> Default for HashMap<K, V, S>
77
where
78
hb::HashMap<K, V, S>: Default,
79
{
80
#[inline]
81
fn default() -> Self {
82
Self(Default::default())
83
}
84
}
85
86
impl<K, V, S> PartialEq for HashMap<K, V, S>
87
where
88
hb::HashMap<K, V, S>: PartialEq,
89
{
90
#[inline]
91
fn eq(&self, other: &Self) -> bool {
92
self.0.eq(&other.0)
93
}
94
}
95
96
impl<K, V, S> Eq for HashMap<K, V, S> where hb::HashMap<K, V, S>: Eq {}
97
98
impl<K, V, S, T> FromIterator<T> for HashMap<K, V, S>
99
where
100
hb::HashMap<K, V, S>: FromIterator<T>,
101
{
102
#[inline]
103
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
104
Self(FromIterator::from_iter(iter))
105
}
106
}
107
108
impl<K, V, S, T> Index<T> for HashMap<K, V, S>
109
where
110
hb::HashMap<K, V, S>: Index<T>,
111
{
112
type Output = <hb::HashMap<K, V, S> as Index<T>>::Output;
113
114
#[inline]
115
fn index(&self, index: T) -> &Self::Output {
116
self.0.index(index)
117
}
118
}
119
120
impl<K, V, S> IntoIterator for HashMap<K, V, S>
121
where
122
hb::HashMap<K, V, S>: IntoIterator,
123
{
124
type Item = <hb::HashMap<K, V, S> as IntoIterator>::Item;
125
126
type IntoIter = <hb::HashMap<K, V, S> as IntoIterator>::IntoIter;
127
128
#[inline]
129
fn into_iter(self) -> Self::IntoIter {
130
self.0.into_iter()
131
}
132
}
133
134
impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
135
where
136
&'a hb::HashMap<K, V, S>: IntoIterator,
137
{
138
type Item = <&'a hb::HashMap<K, V, S> as IntoIterator>::Item;
139
140
type IntoIter = <&'a hb::HashMap<K, V, S> as IntoIterator>::IntoIter;
141
142
#[inline]
143
fn into_iter(self) -> Self::IntoIter {
144
(&self.0).into_iter()
145
}
146
}
147
148
impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
149
where
150
&'a mut hb::HashMap<K, V, S>: IntoIterator,
151
{
152
type Item = <&'a mut hb::HashMap<K, V, S> as IntoIterator>::Item;
153
154
type IntoIter = <&'a mut hb::HashMap<K, V, S> as IntoIterator>::IntoIter;
155
156
#[inline]
157
fn into_iter(self) -> Self::IntoIter {
158
(&mut self.0).into_iter()
159
}
160
}
161
162
impl<K, V, S, T> Extend<T> for HashMap<K, V, S>
163
where
164
hb::HashMap<K, V, S>: Extend<T>,
165
{
166
#[inline]
167
fn extend<U: IntoIterator<Item = T>>(&mut self, iter: U) {
168
self.0.extend(iter);
169
}
170
}
171
172
impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, FixedHasher>
173
where
174
K: Eq + Hash,
175
{
176
fn from(arr: [(K, V); N]) -> Self {
177
arr.into_iter().collect()
178
}
179
}
180
181
impl<K, V, S> From<hb::HashMap<K, V, S>> for HashMap<K, V, S> {
182
#[inline]
183
fn from(value: hb::HashMap<K, V, S>) -> Self {
184
Self(value)
185
}
186
}
187
188
impl<K, V, S> From<HashMap<K, V, S>> for hb::HashMap<K, V, S> {
189
#[inline]
190
fn from(value: HashMap<K, V, S>) -> Self {
191
value.0
192
}
193
}
194
195
impl<K, V, S> Deref for HashMap<K, V, S> {
196
type Target = hb::HashMap<K, V, S>;
197
198
#[inline]
199
fn deref(&self) -> &Self::Target {
200
&self.0
201
}
202
}
203
204
impl<K, V, S> DerefMut for HashMap<K, V, S> {
205
#[inline]
206
fn deref_mut(&mut self) -> &mut Self::Target {
207
&mut self.0
208
}
209
}
210
211
#[cfg(feature = "serialize")]
212
impl<K, V, S> serde::Serialize for HashMap<K, V, S>
213
where
214
hb::HashMap<K, V, S>: serde::Serialize,
215
{
216
#[inline]
217
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
218
where
219
T: serde::Serializer,
220
{
221
self.0.serialize(serializer)
222
}
223
}
224
225
#[cfg(feature = "serialize")]
226
impl<'de, K, V, S> serde::Deserialize<'de> for HashMap<K, V, S>
227
where
228
hb::HashMap<K, V, S>: serde::Deserialize<'de>,
229
{
230
#[inline]
231
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
232
where
233
D: serde::Deserializer<'de>,
234
{
235
Ok(Self(serde::Deserialize::deserialize(deserializer)?))
236
}
237
}
238
239
#[cfg(feature = "rayon")]
240
impl<K, V, S, T> FromParallelIterator<T> for HashMap<K, V, S>
241
where
242
hb::HashMap<K, V, S>: FromParallelIterator<T>,
243
T: Send,
244
{
245
fn from_par_iter<P>(par_iter: P) -> Self
246
where
247
P: IntoParallelIterator<Item = T>,
248
{
249
Self(<hb::HashMap<K, V, S> as FromParallelIterator<T>>::from_par_iter(par_iter))
250
}
251
}
252
253
#[cfg(feature = "rayon")]
254
impl<K, V, S> IntoParallelIterator for HashMap<K, V, S>
255
where
256
hb::HashMap<K, V, S>: IntoParallelIterator,
257
{
258
type Item = <hb::HashMap<K, V, S> as IntoParallelIterator>::Item;
259
type Iter = <hb::HashMap<K, V, S> as IntoParallelIterator>::Iter;
260
261
fn into_par_iter(self) -> Self::Iter {
262
self.0.into_par_iter()
263
}
264
}
265
266
#[cfg(feature = "rayon")]
267
impl<'a, K: Sync, V: Sync, S> IntoParallelIterator for &'a HashMap<K, V, S>
268
where
269
&'a hb::HashMap<K, V, S>: IntoParallelIterator,
270
{
271
type Item = <&'a hb::HashMap<K, V, S> as IntoParallelIterator>::Item;
272
type Iter = <&'a hb::HashMap<K, V, S> as IntoParallelIterator>::Iter;
273
274
fn into_par_iter(self) -> Self::Iter {
275
(&self.0).into_par_iter()
276
}
277
}
278
279
#[cfg(feature = "rayon")]
280
impl<'a, K: Sync, V: Sync, S> IntoParallelIterator for &'a mut HashMap<K, V, S>
281
where
282
&'a mut hb::HashMap<K, V, S>: IntoParallelIterator,
283
{
284
type Item = <&'a mut hb::HashMap<K, V, S> as IntoParallelIterator>::Item;
285
type Iter = <&'a mut hb::HashMap<K, V, S> as IntoParallelIterator>::Iter;
286
287
fn into_par_iter(self) -> Self::Iter {
288
(&mut self.0).into_par_iter()
289
}
290
}
291
292
#[cfg(feature = "rayon")]
293
impl<K, V, S, T> ParallelExtend<T> for HashMap<K, V, S>
294
where
295
hb::HashMap<K, V, S>: ParallelExtend<T>,
296
T: Send,
297
{
298
fn par_extend<I>(&mut self, par_iter: I)
299
where
300
I: IntoParallelIterator<Item = T>,
301
{
302
<hb::HashMap<K, V, S> as ParallelExtend<T>>::par_extend(&mut self.0, par_iter);
303
}
304
}
305
306
impl<K, V> HashMap<K, V, FixedHasher> {
307
/// Creates an empty [`HashMap`].
308
///
309
/// Refer to [`new`](hb::HashMap::new) for further details.
310
///
311
/// # Examples
312
///
313
/// ```rust
314
/// # use bevy_platform::collections::HashMap;
315
/// #
316
/// // Creates a HashMap with zero capacity.
317
/// let map = HashMap::new();
318
/// #
319
/// # let mut map = map;
320
/// # map.insert(0usize, "foo");
321
/// # assert_eq!(map.get(&0), Some("foo").as_ref());
322
/// ```
323
#[inline]
324
pub const fn new() -> Self {
325
Self::with_hasher(FixedHasher)
326
}
327
328
/// Creates an empty [`HashMap`] with the specified capacity.
329
///
330
/// Refer to [`with_capacity`](hb::HashMap::with_capacity) for further details.
331
///
332
/// # Examples
333
///
334
/// ```rust
335
/// # use bevy_platform::collections::HashMap;
336
/// #
337
/// // Creates a HashMap with capacity for at least 5 entries.
338
/// let map = HashMap::with_capacity(5);
339
/// #
340
/// # let mut map = map;
341
/// # map.insert(0usize, "foo");
342
/// # assert_eq!(map.get(&0), Some("foo").as_ref());
343
/// ```
344
#[inline]
345
pub fn with_capacity(capacity: usize) -> Self {
346
Self::with_capacity_and_hasher(capacity, FixedHasher)
347
}
348
}
349
350
impl<K, V, S> HashMap<K, V, S> {
351
/// Creates an empty [`HashMap`] which will use the given hash builder to hash
352
/// keys.
353
///
354
/// Refer to [`with_hasher`](hb::HashMap::with_hasher) for further details.
355
///
356
/// # Examples
357
///
358
/// ```rust
359
/// # use bevy_platform::collections::HashMap;
360
/// # use bevy_platform::hash::FixedHasher as SomeHasher;
361
/// // Creates a HashMap with the provided hasher.
362
/// let map = HashMap::with_hasher(SomeHasher);
363
/// #
364
/// # let mut map = map;
365
/// # map.insert(0usize, "foo");
366
/// # assert_eq!(map.get(&0), Some("foo").as_ref());
367
/// ```
368
#[inline]
369
pub const fn with_hasher(hash_builder: S) -> Self {
370
Self(hb::HashMap::with_hasher(hash_builder))
371
}
372
373
/// Creates an empty [`HashMap`] with the specified capacity, using `hash_builder`
374
/// to hash the keys.
375
///
376
/// Refer to [`with_capacity_and_hasher`](hb::HashMap::with_capacity_and_hasher) for further details.
377
///
378
/// # Examples
379
///
380
/// ```rust
381
/// # use bevy_platform::collections::HashMap;
382
/// # use bevy_platform::hash::FixedHasher as SomeHasher;
383
/// // Creates a HashMap with capacity for 5 entries and the provided hasher.
384
/// let map = HashMap::with_capacity_and_hasher(5, SomeHasher);
385
/// #
386
/// # let mut map = map;
387
/// # map.insert(0usize, "foo");
388
/// # assert_eq!(map.get(&0), Some("foo").as_ref());
389
/// ```
390
#[inline]
391
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
392
Self(hb::HashMap::with_capacity_and_hasher(
393
capacity,
394
hash_builder,
395
))
396
}
397
398
/// Returns a reference to the map's [`BuildHasher`], or `S` parameter.
399
///
400
/// Refer to [`hasher`](hb::HashMap::hasher) for further details.
401
#[inline]
402
pub fn hasher(&self) -> &S {
403
self.0.hasher()
404
}
405
406
/// Returns the number of elements the map can hold without reallocating.
407
///
408
/// Refer to [`capacity`](hb::HashMap::capacity) for further details.
409
///
410
/// # Examples
411
///
412
/// ```rust
413
/// # use bevy_platform::collections::HashMap;
414
/// let map = HashMap::with_capacity(5);
415
///
416
/// # let map: HashMap<(), ()> = map;
417
/// #
418
/// assert!(map.capacity() >= 5);
419
/// ```
420
#[inline]
421
pub fn capacity(&self) -> usize {
422
self.0.capacity()
423
}
424
425
/// An iterator visiting all keys in arbitrary order.
426
/// The iterator element type is `&'a K`.
427
///
428
/// Refer to [`keys`](hb::HashMap::keys) for further details.
429
///
430
/// # Examples
431
///
432
/// ```rust
433
/// # use bevy_platform::collections::HashMap;
434
/// #
435
/// let mut map = HashMap::new();
436
///
437
/// map.insert("foo", 0);
438
/// map.insert("bar", 1);
439
/// map.insert("baz", 2);
440
///
441
/// for key in map.keys() {
442
/// // foo, bar, baz
443
/// // Note that the above order is not guaranteed
444
/// }
445
/// #
446
/// # assert_eq!(map.keys().count(), 3);
447
/// ```
448
#[inline]
449
pub fn keys(&self) -> Keys<'_, K, V> {
450
self.0.keys()
451
}
452
453
/// An iterator visiting all values in arbitrary order.
454
/// The iterator element type is `&'a V`.
455
///
456
/// Refer to [`values`](hb::HashMap::values) for further details.
457
///
458
/// # Examples
459
///
460
/// ```rust
461
/// # use bevy_platform::collections::HashMap;
462
/// #
463
/// let mut map = HashMap::new();
464
///
465
/// map.insert("foo", 0);
466
/// map.insert("bar", 1);
467
/// map.insert("baz", 2);
468
///
469
/// for key in map.values() {
470
/// // 0, 1, 2
471
/// // Note that the above order is not guaranteed
472
/// }
473
/// #
474
/// # assert_eq!(map.values().count(), 3);
475
/// ```
476
#[inline]
477
pub fn values(&self) -> Values<'_, K, V> {
478
self.0.values()
479
}
480
481
/// An iterator visiting all values mutably in arbitrary order.
482
/// The iterator element type is `&'a mut V`.
483
///
484
/// Refer to [`values`](hb::HashMap::values) for further details.
485
///
486
/// # Examples
487
///
488
/// ```rust
489
/// # use bevy_platform::collections::HashMap;
490
/// #
491
/// let mut map = HashMap::new();
492
///
493
/// map.insert("foo", 0);
494
/// map.insert("bar", 1);
495
/// map.insert("baz", 2);
496
///
497
/// for key in map.values_mut() {
498
/// // 0, 1, 2
499
/// // Note that the above order is not guaranteed
500
/// }
501
/// #
502
/// # assert_eq!(map.values_mut().count(), 3);
503
/// ```
504
#[inline]
505
pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
506
self.0.values_mut()
507
}
508
509
/// An iterator visiting all key-value pairs in arbitrary order.
510
/// The iterator element type is `(&'a K, &'a V)`.
511
///
512
/// Refer to [`iter`](hb::HashMap::iter) for further details.
513
///
514
/// # Examples
515
///
516
/// ```rust
517
/// # use bevy_platform::collections::HashMap;
518
/// #
519
/// let mut map = HashMap::new();
520
///
521
/// map.insert("foo", 0);
522
/// map.insert("bar", 1);
523
/// map.insert("baz", 2);
524
///
525
/// for (key, value) in map.iter() {
526
/// // ("foo", 0), ("bar", 1), ("baz", 2)
527
/// // Note that the above order is not guaranteed
528
/// }
529
/// #
530
/// # assert_eq!(map.iter().count(), 3);
531
/// ```
532
#[inline]
533
pub fn iter(&self) -> Iter<'_, K, V> {
534
self.0.iter()
535
}
536
537
/// An iterator visiting all key-value pairs in arbitrary order,
538
/// with mutable references to the values.
539
/// The iterator element type is `(&'a K, &'a mut V)`.
540
///
541
/// Refer to [`iter_mut`](hb::HashMap::iter_mut) for further details.
542
///
543
/// # Examples
544
///
545
/// ```rust
546
/// # use bevy_platform::collections::HashMap;
547
/// #
548
/// let mut map = HashMap::new();
549
///
550
/// map.insert("foo", 0);
551
/// map.insert("bar", 1);
552
/// map.insert("baz", 2);
553
///
554
/// for (key, value) in map.iter_mut() {
555
/// // ("foo", 0), ("bar", 1), ("baz", 2)
556
/// // Note that the above order is not guaranteed
557
/// }
558
/// #
559
/// # assert_eq!(map.iter_mut().count(), 3);
560
/// ```
561
#[inline]
562
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
563
self.0.iter_mut()
564
}
565
566
/// Returns the number of elements in the map.
567
///
568
/// Refer to [`len`](hb::HashMap::len) for further details.
569
///
570
/// # Examples
571
///
572
/// ```rust
573
/// # use bevy_platform::collections::HashMap;
574
/// let mut map = HashMap::new();
575
///
576
/// assert_eq!(map.len(), 0);
577
///
578
/// map.insert("foo", 0);
579
///
580
/// assert_eq!(map.len(), 1);
581
/// ```
582
#[inline]
583
pub fn len(&self) -> usize {
584
self.0.len()
585
}
586
587
/// Returns `true` if the map contains no elements.
588
///
589
/// Refer to [`is_empty`](hb::HashMap::is_empty) for further details.
590
///
591
/// # Examples
592
///
593
/// ```rust
594
/// # use bevy_platform::collections::HashMap;
595
/// let mut map = HashMap::new();
596
///
597
/// assert!(map.is_empty());
598
///
599
/// map.insert("foo", 0);
600
///
601
/// assert!(!map.is_empty());
602
/// ```
603
#[inline]
604
pub fn is_empty(&self) -> bool {
605
self.0.is_empty()
606
}
607
608
/// Clears the map, returning all key-value pairs as an iterator. Keeps the
609
/// allocated memory for reuse.
610
///
611
/// Refer to [`drain`](hb::HashMap::drain) for further details.
612
///
613
/// # Examples
614
///
615
/// ```rust
616
/// # use bevy_platform::collections::HashMap;
617
/// #
618
/// let mut map = HashMap::new();
619
///
620
/// map.insert("foo", 0);
621
/// map.insert("bar", 1);
622
/// map.insert("baz", 2);
623
///
624
/// for (key, value) in map.drain() {
625
/// // ("foo", 0), ("bar", 1), ("baz", 2)
626
/// // Note that the above order is not guaranteed
627
/// }
628
///
629
/// assert!(map.is_empty());
630
/// ```
631
#[inline]
632
pub fn drain(&mut self) -> Drain<'_, K, V> {
633
self.0.drain()
634
}
635
636
/// Retains only the elements specified by the predicate. Keeps the
637
/// allocated memory for reuse.
638
///
639
/// Refer to [`retain`](hb::HashMap::retain) for further details.
640
///
641
/// # Examples
642
///
643
/// ```rust
644
/// # use bevy_platform::collections::HashMap;
645
/// #
646
/// let mut map = HashMap::new();
647
///
648
/// map.insert("foo", 0);
649
/// map.insert("bar", 1);
650
/// map.insert("baz", 2);
651
///
652
/// map.retain(|key, value| *value == 2);
653
///
654
/// assert_eq!(map.len(), 1);
655
/// ```
656
#[inline]
657
pub fn retain<F>(&mut self, f: F)
658
where
659
F: FnMut(&K, &mut V) -> bool,
660
{
661
self.0.retain(f);
662
}
663
664
/// Drains elements which are true under the given predicate,
665
/// and returns an iterator over the removed items.
666
///
667
/// Refer to [`extract_if`](hb::HashMap::extract_if) for further details.
668
///
669
/// # Examples
670
///
671
/// ```rust
672
/// # use bevy_platform::collections::HashMap;
673
/// #
674
/// let mut map = HashMap::new();
675
///
676
/// map.insert("foo", 0);
677
/// map.insert("bar", 1);
678
/// map.insert("baz", 2);
679
///
680
/// let extracted = map
681
/// .extract_if(|key, value| *value == 2)
682
/// .collect::<Vec<_>>();
683
///
684
/// assert_eq!(map.len(), 2);
685
/// assert_eq!(extracted.len(), 1);
686
/// ```
687
#[inline]
688
pub fn extract_if<F>(&mut self, f: F) -> ExtractIf<'_, K, V, F>
689
where
690
F: FnMut(&K, &mut V) -> bool,
691
{
692
self.0.extract_if(f)
693
}
694
695
/// Clears the map, removing all key-value pairs. Keeps the allocated memory
696
/// for reuse.
697
///
698
/// Refer to [`clear`](hb::HashMap::clear) for further details.
699
///
700
/// # Examples
701
///
702
/// ```rust
703
/// # use bevy_platform::collections::HashMap;
704
/// #
705
/// let mut map = HashMap::new();
706
///
707
/// map.insert("foo", 0);
708
/// map.insert("bar", 1);
709
/// map.insert("baz", 2);
710
///
711
/// map.clear();
712
///
713
/// assert!(map.is_empty());
714
/// ```
715
#[inline]
716
pub fn clear(&mut self) {
717
self.0.clear();
718
}
719
720
/// Creates a consuming iterator visiting all the keys in arbitrary order.
721
/// The map cannot be used after calling this.
722
/// The iterator element type is `K`.
723
///
724
/// Refer to [`into_keys`](hb::HashMap::into_keys) for further details.
725
///
726
/// # Examples
727
///
728
/// ```rust
729
/// # use bevy_platform::collections::HashMap;
730
/// #
731
/// let mut map = HashMap::new();
732
///
733
/// map.insert("foo", 0);
734
/// map.insert("bar", 1);
735
/// map.insert("baz", 2);
736
///
737
/// for key in map.into_keys() {
738
/// // "foo", "bar", "baz"
739
/// // Note that the above order is not guaranteed
740
/// }
741
/// ```
742
#[inline]
743
pub fn into_keys(self) -> IntoKeys<K, V> {
744
self.0.into_keys()
745
}
746
747
/// Creates a consuming iterator visiting all the values in arbitrary order.
748
/// The map cannot be used after calling this.
749
/// The iterator element type is `V`.
750
///
751
/// Refer to [`into_values`](hb::HashMap::into_values) for further details.
752
///
753
/// # Examples
754
///
755
/// ```rust
756
/// # use bevy_platform::collections::HashMap;
757
/// #
758
/// let mut map = HashMap::new();
759
///
760
/// map.insert("foo", 0);
761
/// map.insert("bar", 1);
762
/// map.insert("baz", 2);
763
///
764
/// for key in map.into_values() {
765
/// // 0, 1, 2
766
/// // Note that the above order is not guaranteed
767
/// }
768
/// ```
769
#[inline]
770
pub fn into_values(self) -> IntoValues<K, V> {
771
self.0.into_values()
772
}
773
774
/// Takes the inner [`HashMap`](hb::HashMap) out of this wrapper.
775
///
776
/// # Examples
777
///
778
/// ```rust
779
/// # use bevy_platform::collections::HashMap;
780
/// let map: HashMap<&'static str, usize> = HashMap::new();
781
/// let map: hashbrown::HashMap<&'static str, usize, _> = map.into_inner();
782
/// ```
783
#[inline]
784
pub fn into_inner(self) -> hb::HashMap<K, V, S> {
785
self.0
786
}
787
}
788
789
impl<K, V, S> HashMap<K, V, S>
790
where
791
K: Eq + Hash,
792
S: BuildHasher,
793
{
794
/// Reserves capacity for at least `additional` more elements to be inserted
795
/// in the [`HashMap`]. The collection may reserve more space to avoid
796
/// frequent reallocations.
797
///
798
/// Refer to [`reserve`](hb::HashMap::reserve) for further details.
799
///
800
/// # Examples
801
///
802
/// ```rust
803
/// # use bevy_platform::collections::HashMap;
804
/// let mut map = HashMap::with_capacity(5);
805
///
806
/// # let mut map: HashMap<(), ()> = map;
807
/// #
808
/// assert!(map.capacity() >= 5);
809
///
810
/// map.reserve(10);
811
///
812
/// assert!(map.capacity() - map.len() >= 10);
813
/// ```
814
#[inline]
815
pub fn reserve(&mut self, additional: usize) {
816
self.0.reserve(additional);
817
}
818
819
/// Tries to reserve capacity for at least `additional` more elements to be inserted
820
/// in the given `HashMap<K,V>`. The collection may reserve more space to avoid
821
/// frequent reallocations.
822
///
823
/// Refer to [`try_reserve`](hb::HashMap::try_reserve) for further details.
824
///
825
/// # Examples
826
///
827
/// ```rust
828
/// # use bevy_platform::collections::HashMap;
829
/// let mut map = HashMap::with_capacity(5);
830
///
831
/// # let mut map: HashMap<(), ()> = map;
832
/// #
833
/// assert!(map.capacity() >= 5);
834
///
835
/// map.try_reserve(10).expect("Out of Memory!");
836
///
837
/// assert!(map.capacity() - map.len() >= 10);
838
/// ```
839
#[inline]
840
pub fn try_reserve(&mut self, additional: usize) -> Result<(), hashbrown::TryReserveError> {
841
self.0.try_reserve(additional)
842
}
843
844
/// Shrinks the capacity of the map as much as possible. It will drop
845
/// down as much as possible while maintaining the internal rules
846
/// and possibly leaving some space in accordance with the resize policy.
847
///
848
/// Refer to [`shrink_to_fit`](hb::HashMap::shrink_to_fit) for further details.
849
///
850
/// # Examples
851
///
852
/// ```rust
853
/// # use bevy_platform::collections::HashMap;
854
/// let mut map = HashMap::with_capacity(5);
855
///
856
/// map.insert("foo", 0);
857
/// map.insert("bar", 1);
858
/// map.insert("baz", 2);
859
///
860
/// assert!(map.capacity() >= 5);
861
///
862
/// map.shrink_to_fit();
863
///
864
/// assert_eq!(map.capacity(), 3);
865
/// ```
866
#[inline]
867
pub fn shrink_to_fit(&mut self) {
868
self.0.shrink_to_fit();
869
}
870
871
/// Shrinks the capacity of the map with a lower limit. It will drop
872
/// down no lower than the supplied limit while maintaining the internal rules
873
/// and possibly leaving some space in accordance with the resize policy.
874
///
875
/// Refer to [`shrink_to`](hb::HashMap::shrink_to) for further details.
876
#[inline]
877
pub fn shrink_to(&mut self, min_capacity: usize) {
878
self.0.shrink_to(min_capacity);
879
}
880
881
/// Gets the given key's corresponding entry in the map for in-place manipulation.
882
///
883
/// Refer to [`entry`](hb::HashMap::entry) for further details.
884
///
885
/// # Examples
886
///
887
/// ```rust
888
/// # use bevy_platform::collections::HashMap;
889
/// let mut map = HashMap::new();
890
///
891
/// let value = map.entry("foo").or_insert(0);
892
/// #
893
/// # assert_eq!(*value, 0);
894
/// ```
895
#[inline]
896
pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S> {
897
self.0.entry(key)
898
}
899
900
/// Gets the given key's corresponding entry by reference in the map for in-place manipulation.
901
///
902
/// Refer to [`entry_ref`](hb::HashMap::entry_ref) for further details.
903
///
904
/// # Examples
905
///
906
/// ```rust
907
/// # use bevy_platform::collections::HashMap;
908
/// let mut map = HashMap::new();
909
/// # let mut map: HashMap<&'static str, usize> = map;
910
///
911
/// let value = map.entry_ref("foo").or_insert(0);
912
/// #
913
/// # assert_eq!(*value, 0);
914
/// ```
915
#[inline]
916
pub fn entry_ref<'a, 'b, Q>(&'a mut self, key: &'b Q) -> EntryRef<'a, 'b, K, Q, V, S>
917
where
918
Q: Hash + Equivalent<K> + ?Sized,
919
{
920
self.0.entry_ref(key)
921
}
922
923
/// Returns a reference to the value corresponding to the key.
924
///
925
/// Refer to [`get`](hb::HashMap::get) for further details.
926
///
927
/// # Examples
928
///
929
/// ```rust
930
/// # use bevy_platform::collections::HashMap;
931
/// let mut map = HashMap::new();
932
///
933
/// map.insert("foo", 0);
934
///
935
/// assert_eq!(map.get("foo"), Some(&0));
936
/// ```
937
#[inline]
938
pub fn get<Q>(&self, k: &Q) -> Option<&V>
939
where
940
Q: Hash + Equivalent<K> + ?Sized,
941
{
942
self.0.get(k)
943
}
944
945
/// Returns the key-value pair corresponding to the supplied key.
946
///
947
/// Refer to [`get_key_value`](hb::HashMap::get_key_value) for further details.
948
///
949
/// # Examples
950
///
951
/// ```rust
952
/// # use bevy_platform::collections::HashMap;
953
/// let mut map = HashMap::new();
954
///
955
/// map.insert("foo", 0);
956
///
957
/// assert_eq!(map.get_key_value("foo"), Some((&"foo", &0)));
958
/// ```
959
#[inline]
960
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
961
where
962
Q: Hash + Equivalent<K> + ?Sized,
963
{
964
self.0.get_key_value(k)
965
}
966
967
/// Returns the key-value pair corresponding to the supplied key, with a mutable reference to value.
968
///
969
/// Refer to [`get_key_value_mut`](hb::HashMap::get_key_value_mut) for further details.
970
///
971
/// # Examples
972
///
973
/// ```rust
974
/// # use bevy_platform::collections::HashMap;
975
/// let mut map = HashMap::new();
976
///
977
/// map.insert("foo", 0);
978
///
979
/// assert_eq!(map.get_key_value_mut("foo"), Some((&"foo", &mut 0)));
980
/// ```
981
#[inline]
982
pub fn get_key_value_mut<Q>(&mut self, k: &Q) -> Option<(&K, &mut V)>
983
where
984
Q: Hash + Equivalent<K> + ?Sized,
985
{
986
self.0.get_key_value_mut(k)
987
}
988
989
/// Returns `true` if the map contains a value for the specified key.
990
///
991
/// Refer to [`contains_key`](hb::HashMap::contains_key) for further details.
992
///
993
/// # Examples
994
///
995
/// ```rust
996
/// # use bevy_platform::collections::HashMap;
997
/// let mut map = HashMap::new();
998
///
999
/// map.insert("foo", 0);
1000
///
1001
/// assert!(map.contains_key("foo"));
1002
/// ```
1003
#[inline]
1004
pub fn contains_key<Q>(&self, k: &Q) -> bool
1005
where
1006
Q: Hash + Equivalent<K> + ?Sized,
1007
{
1008
self.0.contains_key(k)
1009
}
1010
1011
/// Returns a mutable reference to the value corresponding to the key.
1012
///
1013
/// Refer to [`get_mut`](hb::HashMap::get_mut) for further details.
1014
///
1015
/// # Examples
1016
///
1017
/// ```rust
1018
/// # use bevy_platform::collections::HashMap;
1019
/// let mut map = HashMap::new();
1020
///
1021
/// map.insert("foo", 0);
1022
///
1023
/// assert_eq!(map.get_mut("foo"), Some(&mut 0));
1024
/// ```
1025
#[inline]
1026
pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
1027
where
1028
Q: Hash + Equivalent<K> + ?Sized,
1029
{
1030
self.0.get_mut(k)
1031
}
1032
1033
/// Attempts to get mutable references to `N` values in the map at once.
1034
///
1035
/// Refer to [`get_disjoint_mut`](hb::HashMap::get_disjoint_mut) for further details.
1036
///
1037
/// # Examples
1038
///
1039
/// ```rust
1040
/// # use bevy_platform::collections::HashMap;
1041
/// let mut map = HashMap::new();
1042
///
1043
/// map.insert("foo", 0);
1044
/// map.insert("bar", 1);
1045
/// map.insert("baz", 2);
1046
///
1047
/// let result = map.get_disjoint_mut(["foo", "bar"]);
1048
///
1049
/// assert_eq!(result, [Some(&mut 0), Some(&mut 1)]);
1050
/// ```
1051
#[inline]
1052
pub fn get_disjoint_mut<Q, const N: usize>(&mut self, ks: [&Q; N]) -> [Option<&'_ mut V>; N]
1053
where
1054
Q: Hash + Equivalent<K> + ?Sized,
1055
{
1056
self.0.get_disjoint_mut(ks)
1057
}
1058
1059
/// Attempts to get mutable references to `N` values in the map at once, with immutable
1060
/// references to the corresponding keys.
1061
///
1062
/// Refer to [`get_disjoint_key_value_mut`](hb::HashMap::get_disjoint_key_value_mut) for further details.
1063
///
1064
/// # Examples
1065
///
1066
/// ```rust
1067
/// # use bevy_platform::collections::HashMap;
1068
/// let mut map = HashMap::new();
1069
///
1070
/// map.insert("foo", 0);
1071
/// map.insert("bar", 1);
1072
/// map.insert("baz", 2);
1073
///
1074
/// let result = map.get_disjoint_key_value_mut(["foo", "bar"]);
1075
///
1076
/// assert_eq!(result, [Some((&"foo", &mut 0)), Some((&"bar", &mut 1))]);
1077
/// ```
1078
#[inline]
1079
pub fn get_disjoint_key_value_mut<Q, const N: usize>(
1080
&mut self,
1081
ks: [&Q; N],
1082
) -> [Option<(&'_ K, &'_ mut V)>; N]
1083
where
1084
Q: Hash + Equivalent<K> + ?Sized,
1085
{
1086
self.0.get_disjoint_key_value_mut(ks)
1087
}
1088
1089
/// Inserts a key-value pair into the map.
1090
///
1091
/// Refer to [`insert`](hb::HashMap::insert) for further details.
1092
///
1093
/// # Examples
1094
///
1095
/// ```rust
1096
/// # use bevy_platform::collections::HashMap;
1097
/// let mut map = HashMap::new();
1098
///
1099
/// map.insert("foo", 0);
1100
///
1101
/// assert_eq!(map.get("foo"), Some(&0));
1102
/// ```
1103
#[inline]
1104
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
1105
self.0.insert(k, v)
1106
}
1107
1108
/// Tries to insert a key-value pair into the map, and returns
1109
/// a mutable reference to the value in the entry.
1110
///
1111
/// Refer to [`try_insert`](hb::HashMap::try_insert) for further details.
1112
///
1113
/// # Examples
1114
///
1115
/// ```rust
1116
/// # use bevy_platform::collections::HashMap;
1117
/// let mut map = HashMap::new();
1118
///
1119
/// map.try_insert("foo", 0).unwrap();
1120
///
1121
/// assert!(map.try_insert("foo", 1).is_err());
1122
/// ```
1123
#[inline]
1124
pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, S>> {
1125
self.0.try_insert(key, value)
1126
}
1127
1128
/// Removes a key from the map, returning the value at the key if the key
1129
/// was previously in the map. Keeps the allocated memory for reuse.
1130
///
1131
/// Refer to [`remove`](hb::HashMap::remove) for further details.
1132
///
1133
/// # Examples
1134
///
1135
/// ```rust
1136
/// # use bevy_platform::collections::HashMap;
1137
/// let mut map = HashMap::new();
1138
///
1139
/// map.insert("foo", 0);
1140
///
1141
/// assert_eq!(map.remove("foo"), Some(0));
1142
///
1143
/// assert!(map.is_empty());
1144
/// ```
1145
#[inline]
1146
pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
1147
where
1148
Q: Hash + Equivalent<K> + ?Sized,
1149
{
1150
self.0.remove(k)
1151
}
1152
1153
/// Removes a key from the map, returning the stored key and value if the
1154
/// key was previously in the map. Keeps the allocated memory for reuse.
1155
///
1156
/// Refer to [`remove_entry`](hb::HashMap::remove_entry) for further details.
1157
///
1158
/// # Examples
1159
///
1160
/// ```rust
1161
/// # use bevy_platform::collections::HashMap;
1162
/// let mut map = HashMap::new();
1163
///
1164
/// map.insert("foo", 0);
1165
///
1166
/// assert_eq!(map.remove_entry("foo"), Some(("foo", 0)));
1167
///
1168
/// assert!(map.is_empty());
1169
/// ```
1170
#[inline]
1171
pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
1172
where
1173
Q: Hash + Equivalent<K> + ?Sized,
1174
{
1175
self.0.remove_entry(k)
1176
}
1177
1178
/// Returns the total amount of memory allocated internally by the hash
1179
/// set, in bytes.
1180
///
1181
/// Refer to [`allocation_size`](hb::HashMap::allocation_size) for further details.
1182
///
1183
/// # Examples
1184
///
1185
/// ```rust
1186
/// # use bevy_platform::collections::HashMap;
1187
/// let mut map = HashMap::new();
1188
///
1189
/// assert_eq!(map.allocation_size(), 0);
1190
///
1191
/// map.insert("foo", 0u32);
1192
///
1193
/// assert!(map.allocation_size() >= size_of::<&'static str>() + size_of::<u32>());
1194
/// ```
1195
#[inline]
1196
pub fn allocation_size(&self) -> usize {
1197
self.0.allocation_size()
1198
}
1199
1200
/// Insert a key-value pair into the map without checking
1201
/// if the key already exists in the map.
1202
///
1203
/// Refer to [`insert_unique_unchecked`](hb::HashMap::insert_unique_unchecked) for further details.
1204
///
1205
/// # Safety
1206
///
1207
/// This operation is safe if a key does not exist in the map.
1208
///
1209
/// However, if a key exists in the map already, the behavior is unspecified:
1210
/// this operation may panic, loop forever, or any following operation with the map
1211
/// may panic, loop forever or return arbitrary result.
1212
///
1213
/// That said, this operation (and following operations) are guaranteed to
1214
/// not violate memory safety.
1215
///
1216
/// However this operation is still unsafe because the resulting `HashMap`
1217
/// may be passed to unsafe code which does expect the map to behave
1218
/// correctly, and would cause unsoundness as a result.
1219
#[expect(
1220
unsafe_code,
1221
reason = "re-exporting unsafe method from Hashbrown requires unsafe code"
1222
)]
1223
#[inline]
1224
pub unsafe fn insert_unique_unchecked(&mut self, key: K, value: V) -> (&K, &mut V) {
1225
// SAFETY: safety contract is ensured by the caller.
1226
unsafe { self.0.insert_unique_unchecked(key, value) }
1227
}
1228
1229
/// Attempts to get mutable references to `N` values in the map at once, without validating that
1230
/// the values are unique.
1231
///
1232
/// Refer to [`get_disjoint_unchecked_mut`](hb::HashMap::get_disjoint_unchecked_mut) for further details.
1233
///
1234
/// Returns an array of length `N` with the results of each query. `None` will be used if
1235
/// the key is missing.
1236
///
1237
/// For a safe alternative see [`get_disjoint_mut`](`HashMap::get_disjoint_mut`).
1238
///
1239
/// # Safety
1240
///
1241
/// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1242
/// references are not used.
1243
///
1244
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1245
#[expect(
1246
unsafe_code,
1247
reason = "re-exporting unsafe method from Hashbrown requires unsafe code"
1248
)]
1249
#[inline]
1250
pub unsafe fn get_disjoint_unchecked_mut<Q, const N: usize>(
1251
&mut self,
1252
keys: [&Q; N],
1253
) -> [Option<&'_ mut V>; N]
1254
where
1255
Q: Hash + Equivalent<K> + ?Sized,
1256
{
1257
// SAFETY: safety contract is ensured by the caller.
1258
unsafe { self.0.get_disjoint_unchecked_mut(keys) }
1259
}
1260
1261
/// Attempts to get mutable references to `N` values in the map at once, with immutable
1262
/// references to the corresponding keys, without validating that the values are unique.
1263
///
1264
/// Refer to [`get_disjoint_key_value_unchecked_mut`](hb::HashMap::get_disjoint_key_value_unchecked_mut) for further details.
1265
///
1266
/// Returns an array of length `N` with the results of each query. `None` will be returned if
1267
/// any of the keys are missing.
1268
///
1269
/// For a safe alternative see [`get_disjoint_key_value_mut`](`HashMap::get_disjoint_key_value_mut`).
1270
///
1271
/// # Safety
1272
///
1273
/// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
1274
/// references are not used.
1275
///
1276
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1277
#[expect(
1278
unsafe_code,
1279
reason = "re-exporting unsafe method from Hashbrown requires unsafe code"
1280
)]
1281
#[inline]
1282
pub unsafe fn get_disjoint_key_value_unchecked_mut<Q, const N: usize>(
1283
&mut self,
1284
keys: [&Q; N],
1285
) -> [Option<(&'_ K, &'_ mut V)>; N]
1286
where
1287
Q: Hash + Equivalent<K> + ?Sized,
1288
{
1289
// SAFETY: safety contract is ensured by the caller.
1290
unsafe { self.0.get_disjoint_key_value_unchecked_mut(keys) }
1291
}
1292
}
1293
1294