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