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///
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)]
49pub struct HashMap<K, V, S = FixedHasher>(hb::HashMap<K, V, S>);
50
51impl<K, V, S> Clone for HashMap<K, V, S>
52where
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
66impl<K, V, S> Debug for HashMap<K, V, S>
67where
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
76impl<K, V, S> Default for HashMap<K, V, S>
77where
78 hb::HashMap<K, V, S>: Default,
79{
80 #[inline]
81 fn default() -> Self {
82 Self(Default::default())
83 }
84}
85
86impl<K, V, S> PartialEq for HashMap<K, V, S>
87where
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
96impl<K, V, S> Eq for HashMap<K, V, S> where hb::HashMap<K, V, S>: Eq {}
97
98impl<K, V, S, T> FromIterator<T> for HashMap<K, V, S>
99where
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
108impl<K, V, S, T> Index<T> for HashMap<K, V, S>
109where
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
120impl<K, V, S> IntoIterator for HashMap<K, V, S>
121where
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
134impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
135where
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
148impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
149where
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
162impl<K, V, S, T> Extend<T> for HashMap<K, V, S>
163where
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
172impl<K, V, const N: usize> From<[(K, V); N]> for HashMap<K, V, FixedHasher>
173where
174 K: Eq + Hash,
175{
176 fn from(arr: [(K, V); N]) -> Self {
177 arr.into_iter().collect()
178 }
179}
180
181impl<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
188impl<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
195impl<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
204impl<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")]
212impl<K, V, S> serde::Serialize for HashMap<K, V, S>
213where
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")]
226impl<'de, K, V, S> serde::Deserialize<'de> for HashMap<K, V, S>
227where
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")]
240impl<K, V, S, T> FromParallelIterator<T> for HashMap<K, V, S>
241where
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")]
254impl<K, V, S> IntoParallelIterator for HashMap<K, V, S>
255where
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")]
267impl<'a, K: Sync, V: Sync, S> IntoParallelIterator for &'a HashMap<K, V, S>
268where
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")]
280impl<'a, K: Sync, V: Sync, S> IntoParallelIterator for &'a mut HashMap<K, V, S>
281where
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")]
293impl<K, V, S, T> ParallelExtend<T> for HashMap<K, V, S>
294where
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
306impl<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
350impl<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
789impl<K, V, S> HashMap<K, V, S>
790where
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_many_mut`](hb::HashMap::get_many_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_many_mut(["foo", "bar"]);
1048 ///
1049 /// assert_eq!(result, [Some(&mut 0), Some(&mut 1)]);
1050 /// ```
1051 #[inline]
1052 pub fn get_many_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_many_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_many_key_value_mut`](hb::HashMap::get_many_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_many_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_many_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_many_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_many_unchecked_mut`](hb::HashMap::get_many_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_many_mut`](`HashMap::get_many_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_many_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_many_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_many_key_value_unchecked_mut`](hb::HashMap::get_many_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_many_key_value_mut`](`HashMap::get_many_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_many_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_many_key_value_unchecked_mut(keys) }
1291 }
1292}