bumpish/map.rs
1#![doc = include_str!("../docs/map.md")]
2
3mod bucket;
4mod entry;
5mod inner;
6mod iter;
7
8pub use self::entry::{Entry, OccupiedEntry};
9pub use self::iter::{IntoIter, Iter, IterMut, Keys, Values, ValuesMut};
10
11use self::inner::MapCore;
12use core::fmt::{self, Debug};
13use core::hash::{BuildHasher, Hash};
14use equivalent::Equivalent;
15
16#[cfg(feature = "std")]
17use std::hash::RandomState;
18
19/// A hash map that uses bump allocation inside.
20///
21/// Read [this module documentation](crate::map) for more details.
22#[cfg(feature = "std")]
23pub struct BumpMap<K, V, S = RandomState> {
24 core: MapCore<K, V>,
25 hasher: S,
26}
27
28/// A hash map that uses bump allocation inside.
29///
30/// Read [this module documentation](crate::map) for more details.
31#[cfg(not(feature = "std"))]
32pub struct BumpMap<K, V, S> {
33 core: MapCore<K, V>,
34 hasher: S,
35}
36
37#[cfg(feature = "std")]
38impl<K, V> BumpMap<K, V, RandomState> {
39 /// Creates an empty `BumpMap`.
40 ///
41 /// The new map will not allocate until it is first pair inserted into.
42 ///
43 /// # Examples
44 ///
45 /// ```
46 /// # use bumpish::BumpMap;
47 /// let mut map: BumpMap<&str, i32> = BumpMap::new();
48 /// assert_eq!(map.capacity(), 0);
49 /// ```
50 #[inline]
51 #[must_use]
52 pub fn new() -> Self {
53 Default::default()
54 }
55
56 /// Creates an empty `BumpMap` with at least the specified capacity.
57 ///
58 /// The hash map will be able to hold at least `capacity` elements without
59 /// reallocating. This method is allowed to allocate for more elements than
60 /// `capacity`. If `capacity` is zero, the hash map will not allocate.
61 ///
62 /// # Examples
63 ///
64 /// ```
65 /// # use bumpish::BumpMap;
66 /// let map: BumpMap<&str, i32> = BumpMap::with_capacity(10);
67 /// assert!(map.capacity() >= 10);
68 /// ```
69 #[inline]
70 #[must_use]
71 pub fn with_capacity(capacity: usize) -> Self {
72 Self::with_capacity_and_hasher(capacity, Default::default())
73 }
74}
75
76impl<K, V, S> BumpMap<K, V, S> {
77 /// Creates an empty `BumpMap` which will use the given hash builder to hash
78 /// keys.
79 ///
80 /// The new map will not allocate until it is first pair inserted into.
81 ///
82 /// # Examples
83 ///
84 /// ```
85 /// use bumpish::BumpMap;
86 /// use std::hash::RandomState;
87 ///
88 /// let s = RandomState::new();
89 /// let mut map = BumpMap::with_hasher(s);
90 /// map.insert(1, 2);
91 /// ```
92 pub const fn with_hasher(hasher: S) -> Self {
93 Self {
94 core: MapCore::new(),
95 hasher,
96 }
97 }
98
99 /// Creates an empty `BumpMap` with at least the specified capacity, using
100 /// `hasher` to hash the keys.
101 ///
102 /// The map will be able to hold at least `capacity` elements without
103 /// reallocating. This method is allowed to allocate for more elements than
104 /// `capacity`. If `capacity` is zero, the hash map will not allocate.
105 ///
106 /// # Examples
107 ///
108 /// ```
109 /// use bumpish::BumpMap;
110 /// use std::hash::RandomState;
111 ///
112 /// let s = RandomState::new();
113 /// let mut map = BumpMap::with_capacity_and_hasher(10, s);
114 /// map.insert(1, 2);
115 /// assert!(map.capacity() >= 10);
116 /// ```
117 pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
118 Self {
119 core: MapCore::with_capacity(capacity),
120 hasher: hash_builder,
121 }
122 }
123
124 /// Returns the number of elements the map can hold without reallocating.
125 ///
126 /// # Examples
127 ///
128 /// ```
129 /// # use bumpish::BumpMap;
130 /// let map: BumpMap<i32, i32> = BumpMap::with_capacity(100);
131 /// assert!(map.capacity() >= 100);
132 /// ```
133 #[inline]
134 pub fn capacity(&self) -> usize {
135 self.core.capacity()
136 }
137
138 /// Returns the number of elements in the map.
139 ///
140 /// # Examples
141 ///
142 /// ```
143 /// # use bumpish::BumpMap;
144 /// let mut a = BumpMap::new();
145 /// assert_eq!(a.len(), 0);
146 /// a.insert(1, "a");
147 /// assert_eq!(a.len(), 1);
148 /// ```
149 #[inline]
150 pub fn len(&self) -> usize {
151 self.core.len()
152 }
153
154 /// Returns `true` if the map contains no elements.
155 ///
156 /// # Examples
157 ///
158 /// ```
159 /// # use bumpish::BumpMap;
160 /// let mut a = BumpMap::new();
161 /// assert!(a.is_empty());
162 /// a.insert(1, "a");
163 /// assert!(!a.is_empty());
164 /// ```
165 #[inline]
166 pub fn is_empty(&self) -> bool {
167 self.len() == 0
168 }
169
170 /// Clears the map, removing all key-value pairs. Can keep some of the
171 /// allocated memory for reuse.
172 ///
173 /// # Examples
174 ///
175 /// ```
176 /// # use bumpish::BumpMap;
177 /// let mut a = BumpMap::new();
178 /// a.insert(1, "a");
179 /// a.clear();
180 /// assert!(a.is_empty());
181 /// ```
182 pub fn clear(&mut self) {
183 self.core.clear();
184 }
185
186 /// An iterator visiting all key-value pairs in insertion order. The
187 /// iterator element type is `(&'a K, &'a V)`.
188 ///
189 /// # Examples
190 ///
191 /// ```
192 /// use bumpish::BumpMap;
193 ///
194 /// let map = BumpMap::from([
195 /// ("a", 1),
196 /// ("b", 2),
197 /// ("c", 3),
198 /// ]);
199 ///
200 /// assert_eq!(
201 /// map.iter().collect::<Vec<(_, _)>>(),
202 /// [(&"a", &1), (&"b", &2), (&"c", &3)]
203 /// );
204 /// ```
205 pub fn iter(&self) -> Iter<'_, K, V> {
206 Iter::new(&self.core.entries)
207 }
208
209 /// An iterator visiting all key-value pairs in insertion order, with
210 /// mutable references to the values. The iterator element type is `(&'a K,
211 /// &'a mut V)`.
212 ///
213 /// # Examples
214 ///
215 /// ```
216 /// use bumpish::BumpMap;
217 ///
218 /// let mut map = BumpMap::from([
219 /// ("a", 1),
220 /// ("b", 2),
221 /// ("c", 3),
222 /// ]);
223 ///
224 /// // Update all values
225 /// for (_, val) in map.iter_mut() {
226 /// *val *= 2;
227 /// }
228 ///
229 /// assert_eq!(
230 /// map.iter().collect::<Vec<(_, _)>>(),
231 /// [(&"a", &2), (&"b", &4), (&"c", &6)]
232 /// );
233 /// ```
234 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
235 IterMut::new(&mut self.core.entries)
236 }
237
238 /// An iterator visiting all keys in insertion order. The iterator element
239 /// type is `&'a K`.
240 ///
241 /// # Examples
242 ///
243 /// ```
244 /// use bumpish::BumpMap;
245 ///
246 /// let map = BumpMap::from([
247 /// ("a", 1),
248 /// ("b", 2),
249 /// ("c", 3),
250 /// ]);
251 ///
252 /// for key in map.keys() {
253 /// println!("{key}");
254 /// }
255 /// ```
256 pub fn keys(&self) -> Keys<'_, K, V> {
257 Keys::new(&self.core.entries)
258 }
259
260 /// An iterator visiting all values in insertion order. The iterator element
261 /// type is `&'a V`.
262 ///
263 /// # Examples
264 ///
265 /// ```
266 /// use bumpish::BumpMap;
267 ///
268 /// let map = BumpMap::from([
269 /// ("a", 1),
270 /// ("b", 2),
271 /// ("c", 3),
272 /// ]);
273 ///
274 /// for val in map.values() {
275 /// println!("{val}");
276 /// }
277 /// ```
278 pub fn values(&self) -> Values<'_, K, V> {
279 Values::new(&self.core.entries)
280 }
281
282 /// An iterator visiting all values mutably in insertion order. The iterator
283 /// element type is `&'a mut V`.
284 ///
285 /// # Examples
286 ///
287 /// ```
288 /// use bumpish::BumpMap;
289 ///
290 /// let mut map = BumpMap::from([
291 /// ("a", 1),
292 /// ("b", 2),
293 /// ("c", 3),
294 /// ]);
295 ///
296 /// for val in map.values_mut() {
297 /// *val = *val + 10;
298 /// }
299 ///
300 /// for val in map.values() {
301 /// println!("{val}");
302 /// }
303 /// ```
304 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
305 ValuesMut::new(&mut self.core.entries)
306 }
307}
308
309impl<K, V, S> BumpMap<K, V, S>
310where
311 S: BuildHasher,
312{
313 /// Returns a reference to the map's [`BuildHasher`].
314 ///
315 /// [`BuildHasher`]: https://doc.rust-lang.org/beta/std/hash/trait.BuildHasher.html
316 ///
317 /// # Examples
318 ///
319 /// ```
320 /// use bumpish::BumpMap;
321 /// use std::hash::RandomState;
322 ///
323 /// let hasher = RandomState::new();
324 /// let map: BumpMap<i32, i32> = BumpMap::with_hasher(hasher);
325 /// let hasher: &RandomState = map.hasher();
326 /// ```
327 pub fn hasher(&self) -> &S {
328 &self.hasher
329 }
330
331 /// Returns `true` if the map contains a value with an equivalent key to `key`.
332 ///
333 /// The `Q` type **must** hash like `K`.
334 ///
335 /// # Examples
336 ///
337 /// ```
338 /// # use bumpish::BumpMap;
339 /// let mut map = BumpMap::new();
340 /// map.insert("a".to_owned(), 1);
341 /// assert_eq!(map.contains_key("a"), true);
342 /// assert_eq!(map.contains_key(&"a".to_owned()), true);
343 /// assert_eq!(map.contains_key("b"), false);
344 /// ```
345 pub fn contains_key<Q>(&self, key: &Q) -> bool
346 where
347 Q: ?Sized + Hash + Equivalent<K>,
348 {
349 self.core.contains_key(|| self.hasher.hash_one(key), key)
350 }
351
352 /// Returns a reference to the value corresponding to the key.
353 ///
354 /// The `Q` type **must** hash like `K`.
355 ///
356 /// # Examples
357 ///
358 /// ```
359 /// # use bumpish::BumpMap;
360 /// let mut map = BumpMap::new();
361 /// map.insert(1, "a");
362 /// assert_eq!(map.get(&1), Some(&"a"));
363 /// assert_eq!(map.get(&2), None);
364 /// ```
365 pub fn get<Q>(&self, key: &Q) -> Option<&V>
366 where
367 Q: ?Sized + Hash + Equivalent<K>,
368 {
369 let hash = self.hasher.hash_one(key);
370 self.core.get_key_value(hash, key).map(|(_, value)| value)
371 }
372
373 /// Returns the key-value pair corresponding to the supplied key. This is
374 /// potentially useful:
375 /// - for key types where non-identical keys can be considered equal;
376 /// - for getting the `&K` stored key value from an equivalent `&Q` lookup key; or
377 /// - for getting a reference to a key with the same lifetime as the collection.
378 ///
379 /// The `Q` type **must** hash like `K`.
380 ///
381 /// # Examples
382 ///
383 /// ```
384 /// use bumpish::BumpMap;
385 /// use std::hash::{Hash, Hasher};
386 ///
387 /// #[derive(Clone, Copy, Debug)]
388 /// struct S {
389 /// id: u32,
390 /// # #[allow(unused)]
391 /// name: &'static str, // ignored by equality and hashing operations
392 /// }
393 ///
394 /// impl PartialEq for S {
395 /// fn eq(&self, other: &S) -> bool {
396 /// self.id == other.id
397 /// }
398 /// }
399 ///
400 /// impl Eq for S {}
401 ///
402 /// impl Hash for S {
403 /// fn hash<H: Hasher>(&self, state: &mut H) {
404 /// self.id.hash(state);
405 /// }
406 /// }
407 ///
408 /// let j_a = S { id: 1, name: "Jessica" };
409 /// let j_b = S { id: 1, name: "Jess" };
410 /// let p = S { id: 2, name: "Paul" };
411 /// assert_eq!(j_a, j_b);
412 ///
413 /// let mut map = BumpMap::new();
414 /// map.insert(j_a, "Paris");
415 /// assert_eq!(map.get_key_value(&j_a), Some((&j_a, &"Paris")));
416 /// assert_eq!(map.get_key_value(&j_b), Some((&j_a, &"Paris"))); // the notable case
417 /// assert_eq!(map.get_key_value(&p), None);
418 /// ```
419 pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
420 where
421 Q: ?Sized + Hash + Equivalent<K>,
422 {
423 let hash = self.hasher.hash_one(key);
424 self.core.get_key_value(hash, key)
425 }
426
427 /// Returns a mutable reference to the value corresponding to the key.
428 ///
429 /// The `Q` type **must** hash like `K`.
430 ///
431 /// # Examples
432 ///
433 /// ```
434 /// # use bumpish::BumpMap;
435 ///
436 /// let mut map = BumpMap::new();
437 /// map.insert(1, "a");
438 /// if let Some(x) = map.get_mut(&1) {
439 /// *x = "b";
440 /// }
441 /// assert_eq!(map[&1], "b");
442 /// ```
443 pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
444 where
445 Q: ?Sized + Hash + Equivalent<K>,
446 {
447 let hash = self.hasher.hash_one(key);
448 self.core.get_mut(hash, key)
449 }
450}
451
452impl<K, V, S> BumpMap<K, V, S>
453where
454 K: Hash + Eq,
455 S: BuildHasher,
456{
457 /// Inserts a key-value pair into the map if an equivalent key is not
458 /// present.
459 ///
460 /// If the new key-value pair is inserted, it returns a shared reference to
461 /// the value. Otherwise, it returns `None`.
462 ///
463 /// # Examples
464 ///
465 /// ```
466 /// # use bumpish::BumpMap;
467 /// let mut map = BumpMap::new();
468 ///
469 /// assert_eq!(map.insert(37, "a"), Some(&"a"));
470 /// assert_eq!(map.insert(37, "b"), None);
471 /// assert_eq!(map[&37], "a");
472 /// ```
473 pub fn insert(&self, key: K, value: V) -> Option<&V> {
474 let hash = self.hasher.hash_one(&key);
475 let ptr = self.core.insert(hash, key, value).ok();
476 ptr.map(|ptr| unsafe { &ptr.as_ref().value })
477 }
478
479 /// Inserts a key-value pair into the map if an equivalent key is not
480 /// present.
481 ///
482 /// If the new key-value pair is inserted, it returns a tuple of shared
483 /// references to both key and value. Otherwise, it returns `None`.
484 ///
485 /// # Examples
486 ///
487 /// ```
488 /// # use bumpish::BumpMap;
489 /// let mut map = BumpMap::new();
490 ///
491 /// assert_eq!(map.insert_full(37, "a"), Some((&37, &"a")));
492 /// assert_eq!(map.insert_full(37, "b"), None);
493 /// assert_eq!(map[&37], "a");
494 /// ```
495 pub fn insert_full(&self, key: K, value: V) -> Option<(&K, &V)> {
496 let hash = self.hasher.hash_one(&key);
497 let ptr = self.core.insert(hash, key, value).ok();
498 ptr.map(|ptr| unsafe { ptr.as_ref().as_tuple() })
499 }
500
501 /// Inserts a key-value pair into the map if an equivalent key is not
502 /// present.
503 ///
504 /// If the new key-value pair is inserted, it returns a mutable reference
505 /// to the value. Otherwise, it returns `None`.
506 ///
507 /// # Examples
508 ///
509 /// ```
510 /// # use bumpish::BumpMap;
511 /// let mut map = BumpMap::new();
512 ///
513 /// assert_eq!(map.insert_mut(37, "a"), Some(&mut "a"));
514 /// assert_eq!(map.insert_mut(37, "b"), None);
515 /// assert_eq!(map[&37], "a");
516 /// ```
517 pub fn insert_mut(&mut self, key: K, value: V) -> Option<&mut V> {
518 let hash = self.hasher.hash_one(&key);
519 let ptr = self.core.insert(hash, key, value).ok();
520 ptr.map(|mut ptr| unsafe { &mut ptr.as_mut().value })
521 }
522
523 /// Inserts a key-value pair into the map if an equivalent key is not
524 /// present.
525 ///
526 /// If the new key-value pair is inserted, it returns a tuple of shared
527 /// reference to key and mutable reference to value. Otherwise, it returns
528 /// `None`.
529 ///
530 /// # Examples
531 ///
532 /// ```
533 /// # use bumpish::BumpMap;
534 /// let mut map = BumpMap::new();
535 ///
536 /// assert_eq!(map.insert_full(37, "a"), Some((&37, &"a")));
537 /// assert_eq!(map.insert_full(37, "b"), None);
538 /// assert_eq!(map[&37], "a");
539 /// ```
540 pub fn insert_full_mut(&mut self, key: K, value: V) -> Option<(&K, &mut V)> {
541 let hash = self.hasher.hash_one(&key);
542 let ptr = self.core.insert(hash, key, value).ok();
543 ptr.map(|mut ptr| unsafe { ptr.as_mut().as_tuple_mut() })
544 }
545
546 /// Replaces the value associated with the given key. If an equivalent key
547 /// is not present, inserts a new key-value pair.
548 ///
549 /// Returns the old value if it existed, otherwise returns `None`.
550 ///
551 /// # Examples
552 ///
553 /// ```
554 /// # use bumpish::BumpMap;
555 /// let mut map = BumpMap::new();
556 /// assert_eq!(map.replace(37, "a"), None);
557 /// assert_eq!(map.replace(37, "b"), Some("a"));
558 /// ```
559 pub fn replace(&mut self, key: K, value: V) -> Option<V> {
560 let hash = self.hasher.hash_one(&key);
561 self.core.update(hash, key, value)
562 }
563
564 /// Replaces both key and value associated with the given key. If an
565 /// equivalent key is not present, inserts a new key-value pair.
566 ///
567 /// Returns the old key and value if they existed, otherwise returns `None`.
568 ///
569 /// # Examples
570 ///
571 /// ```
572 /// # use bumpish::BumpMap;
573 /// let mut map = BumpMap::new();
574 /// assert_eq!(map.replace_full(37, "a"), None);
575 /// assert_eq!(map.replace_full(37, "b"), Some((37, "a")));
576 /// ```
577 pub fn replace_full(&mut self, key: K, value: V) -> Option<(K, V)> {
578 let hash = self.hasher.hash_one(&key);
579 self.core.update_full(hash, key, value)
580 }
581
582 /// Gets the given key's corresponding entry in the map.
583 ///
584 /// As distinct from standard `HashMap::entry`, this method returns an
585 /// `Entry` that can't be used to modify the value associated with the key.
586 /// That allows to call `entry` method with a shared reference to the map.
587 ///
588 /// But this still allows to insert a new key-value pair into the vacant
589 /// entry.
590 ///
591 /// # Examples
592 ///
593 /// ```
594 /// use bumpish::BumpMap;
595 ///
596 /// let mut letters = BumpMap::new();
597 ///
598 /// for ch in "a short treatise on fungi".chars() {
599 /// letters.entry(ch).or_insert(true);
600 /// }
601 ///
602 /// assert_eq!(letters[&'s'], true);
603 /// assert_eq!(letters[&'t'], true);
604 /// assert_eq!(letters[&'u'], true);
605 /// assert_eq!(letters.get(&'y'), None);
606 /// ```
607 pub fn entry(&self, key: K) -> Entry<'_, K, V> {
608 let hash = self.hasher.hash_one(&key);
609 self.core.entry(hash, key)
610 }
611}
612
613impl<K, V, S> BumpMap<K, V, S>
614where
615 K: Eq + Hash,
616 S: BuildHasher,
617{
618 /// Augment the map with the contents of an iterator. If a key (the first
619 /// element of a tuple) already exists in this map, the key and
620 /// corresponding value are dropped.
621 ///
622 /// Unlike `Extend` trait, this method does not replace existing entries,
623 /// and requires a shared reference to the map.
624 ///
625 /// # Examples
626 ///
627 /// ```
628 /// # use bumpish::BumpMap;
629 /// let ages = BumpMap::new();
630 ///
631 /// ages.augment([("John", 18), ("Anna", 24), ("Lily", 99)]);
632 ///
633 /// assert_eq!(ages[&"John"], 18);
634 /// assert_eq!(ages[&"Anna"], 24);
635 /// assert_eq!(ages[&"Lily"], 99);
636 ///
637 /// ages.augment([("John", 25), ("Anna", 3), ("Will", 54)]);
638 ///
639 /// assert_eq!(ages[&"John"], 18); // keeps the old value
640 /// assert_eq!(ages[&"Anna"], 24); // keeps the old value
641 /// assert_eq!(ages[&"Lily"], 99);
642 /// assert_eq!(ages[&"Will"], 54);
643 /// ```
644 pub fn augment<I>(&self, iter: I)
645 where
646 I: IntoIterator<Item = (K, V)>,
647 {
648 for (k, v) in iter {
649 let hash = self.hasher.hash_one(&k);
650 _ = self.core.insert(hash, k, v);
651 }
652 }
653}
654
655impl<K, V, S> core::clone::Clone for BumpMap<K, V, S>
656where
657 K: Clone,
658 V: Clone,
659 S: Clone,
660{
661 fn clone(&self) -> Self {
662 Self {
663 core: self.core.clone(),
664 hasher: self.hasher.clone(),
665 }
666 }
667}
668
669impl<K, V, S> Debug for BumpMap<K, V, S>
670where
671 K: Debug,
672 V: Debug,
673{
674 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
675 f.debug_map().entries(self.iter()).finish()
676 }
677}
678
679impl<K, V, S> Default for BumpMap<K, V, S>
680where
681 S: Default,
682{
683 /// Creates an empty `BumpMap<K, V, S>`, with the `Default` value for the hasher.
684 #[inline]
685 fn default() -> Self {
686 Self::with_hasher(Default::default())
687 }
688}
689
690impl<K, V, S> PartialEq for BumpMap<K, V, S>
691where
692 K: Eq + Hash,
693 V: PartialEq,
694 S: BuildHasher,
695{
696 fn eq(&self, other: &Self) -> bool {
697 if self.len() != other.len() {
698 return false;
699 }
700 self.iter().all(|(k, v)| other.get(k) == Some(v))
701 }
702}
703
704impl<K, V, S> Eq for BumpMap<K, V, S>
705where
706 K: Eq + Hash,
707 V: Eq,
708 S: BuildHasher,
709{
710}
711
712#[cfg(feature = "std")]
713impl<K, V, const N: usize> From<[(K, V); N]> for BumpMap<K, V, RandomState>
714where
715 K: Eq + Hash,
716{
717 /// Converts a `[(K, V); N]` into a `BumpMap<K, V>`.
718 ///
719 /// If any entries in the array have equal keys, all but one of the
720 /// corresponding values will be dropped.
721 ///
722 /// # Examples
723 ///
724 /// ```
725 /// # use bumpish::BumpMap;
726 /// let map1 = BumpMap::from([(1, 2), (3, 4)]);
727 /// let map2: BumpMap<_, _> = [(1, 2), (3, 4)].into();
728 /// assert_eq!(map1, map2);
729 /// ```
730 fn from(arr: [(K, V); N]) -> Self {
731 Self::from_iter(arr)
732 }
733}
734
735impl<K, V, S> FromIterator<(K, V)> for BumpMap<K, V, S>
736where
737 K: Eq + Hash,
738 S: BuildHasher + Default,
739{
740 /// Constructs a `BumpMap<K, V>` from an iterator of key-value pairs.
741 ///
742 /// If the iterator produces any pairs with equal keys, all but one of the
743 /// corresponding values will be dropped.
744 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
745 let map = Self::with_hasher(Default::default());
746 for (k, v) in iter {
747 map.insert(k, v);
748 }
749 map
750 }
751}
752
753impl<'a, K, V, S> Extend<(&'a K, &'a V)> for BumpMap<K, V, S>
754where
755 K: Eq + Hash + Copy,
756 V: Copy,
757 S: BuildHasher,
758{
759 fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
760 self.extend(iter.into_iter().map(|(k, v)| (*k, *v)));
761 }
762}
763
764impl<K, V, S> Extend<(K, V)> for BumpMap<K, V, S>
765where
766 K: Eq + Hash,
767 S: BuildHasher,
768{
769 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
770 for (k, v) in iter {
771 self.replace(k, v);
772 }
773 }
774}
775
776impl<K, Q: ?Sized, V, S> core::ops::Index<&Q> for BumpMap<K, V, S>
777where
778 K: Eq + Hash,
779 Q: Eq + Hash + Equivalent<K>,
780 S: BuildHasher,
781{
782 type Output = V;
783
784 /// Returns a reference to the value corresponding to the supplied key.
785 ///
786 /// # Panics
787 ///
788 /// Panics if the key is not present in the `BumpMap`.
789 #[inline]
790 fn index(&self, key: &Q) -> &Self::Output {
791 self.get(key).expect("no entry found for key")
792 }
793}
794
795impl<'a, K, V, S> IntoIterator for &'a BumpMap<K, V, S> {
796 type Item = (&'a K, &'a V);
797 type IntoIter = Iter<'a, K, V>;
798
799 #[inline]
800 fn into_iter(self) -> Iter<'a, K, V> {
801 self.iter()
802 }
803}
804
805impl<'a, K, V, S> IntoIterator for &'a mut BumpMap<K, V, S> {
806 type Item = (&'a K, &'a mut V);
807 type IntoIter = IterMut<'a, K, V>;
808
809 #[inline]
810 fn into_iter(self) -> IterMut<'a, K, V> {
811 self.iter_mut()
812 }
813}
814
815impl<K, V, S> IntoIterator for BumpMap<K, V, S> {
816 type Item = (K, V);
817 type IntoIter = IntoIter<K, V>;
818
819 #[inline]
820 fn into_iter(self) -> IntoIter<K, V> {
821 IntoIter::new(self.core.entries)
822 }
823}