heapless/index_map.rs
1//! A fixed-capacity hash table where the iteration order is independent of the hash of the keys.
2use core::{
3 borrow::Borrow,
4 fmt,
5 hash::{BuildHasher, Hash},
6 mem,
7 num::NonZeroU32,
8 ops, slice,
9};
10
11use hash32::{BuildHasherDefault, FnvHasher};
12
13use crate::Vec;
14
15/// An [`IndexMap`] using the default FNV hasher.
16///
17/// A list of all Methods and Traits available for `FnvIndexMap` can be found in
18/// the [`IndexMap`] documentation.
19///
20/// # Examples
21/// ```
22/// use heapless::index_map::FnvIndexMap;
23///
24/// // A hash map with a capacity of 16 key-value pairs allocated on the stack
25/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
26///
27/// // review some books.
28/// book_reviews
29/// .insert("Adventures of Huckleberry Finn", "My favorite book.")
30/// .unwrap();
31/// book_reviews
32/// .insert("Grimms' Fairy Tales", "Masterpiece.")
33/// .unwrap();
34/// book_reviews
35/// .insert("Pride and Prejudice", "Very enjoyable.")
36/// .unwrap();
37/// book_reviews
38/// .insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.")
39/// .unwrap();
40///
41/// // check for a specific one.
42/// if !book_reviews.contains_key("Les Misérables") {
43/// println!(
44/// "We've got {} reviews, but Les Misérables ain't one.",
45/// book_reviews.len()
46/// );
47/// }
48///
49/// // oops, this review has a lot of spelling mistakes, let's delete it.
50/// book_reviews.remove("The Adventures of Sherlock Holmes");
51///
52/// // look up the values associated with some keys.
53/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
54/// for book in &to_find {
55/// match book_reviews.get(book) {
56/// Some(review) => println!("{}: {}", book, review),
57/// None => println!("{} is unreviewed.", book),
58/// }
59/// }
60///
61/// // iterate over everything.
62/// for (book, review) in &book_reviews {
63/// println!("{}: \"{}\"", book, review);
64/// }
65/// ```
66pub type FnvIndexMap<K, V, const N: usize> = IndexMap<K, V, BuildHasherDefault<FnvHasher>, N>;
67
68#[derive(Clone, Copy, Eq, PartialEq)]
69struct HashValue(u16);
70
71impl HashValue {
72 fn desired_pos(&self, mask: usize) -> usize {
73 usize::from(self.0) & mask
74 }
75
76 fn probe_distance(&self, mask: usize, current: usize) -> usize {
77 current.wrapping_sub(self.desired_pos(mask)) & mask
78 }
79}
80
81#[doc(hidden)]
82#[derive(Clone)]
83pub struct Bucket<K, V> {
84 hash: HashValue,
85 key: K,
86 value: V,
87}
88
89#[doc(hidden)]
90#[derive(Clone, Copy, PartialEq)]
91pub struct Pos {
92 // compact representation of `{ hash_value: u16, index: u16 }`
93 // To get the most from `NonZero` we store the *value minus 1*. This way `None::Option<Pos>`
94 // is equivalent to the very unlikely value of `{ hash_value: 0xffff, index: 0xffff }` instead
95 // the more likely of `{ hash_value: 0x00, index: 0x00 }`
96 nz: NonZeroU32,
97}
98
99impl Pos {
100 fn new(index: usize, hash: HashValue) -> Self {
101 Self {
102 nz: unsafe {
103 NonZeroU32::new_unchecked(
104 ((u32::from(hash.0) << 16) + index as u32).wrapping_add(1),
105 )
106 },
107 }
108 }
109
110 fn hash(&self) -> HashValue {
111 HashValue((self.nz.get().wrapping_sub(1) >> 16) as u16)
112 }
113
114 fn index(&self) -> usize {
115 self.nz.get().wrapping_sub(1) as u16 as usize
116 }
117}
118
119enum Insert<K, V> {
120 Success(Inserted<V>),
121 Full((K, V)),
122}
123struct Inserted<V> {
124 index: usize,
125 old_value: Option<V>,
126}
127
128macro_rules! probe_loop {
129 ($probe_var: ident < $len: expr, $body: expr) => {
130 loop {
131 if $probe_var < $len {
132 $body
133 $probe_var += 1;
134 } else {
135 $probe_var = 0;
136 }
137 }
138 }
139}
140
141struct CoreMap<K, V, const N: usize> {
142 entries: Vec<Bucket<K, V>, N, usize>,
143 indices: [Option<Pos>; N],
144}
145
146impl<K, V, const N: usize> CoreMap<K, V, N> {
147 const fn new() -> Self {
148 const INIT: Option<Pos> = None;
149
150 Self {
151 entries: Vec::new(),
152 indices: [INIT; N],
153 }
154 }
155}
156
157impl<K, V, const N: usize> CoreMap<K, V, N>
158where
159 K: Eq + Hash,
160{
161 fn capacity() -> usize {
162 N
163 }
164
165 fn mask() -> usize {
166 Self::capacity() - 1
167 }
168
169 fn find<Q>(&self, hash: HashValue, query: &Q) -> Option<(usize, usize)>
170 where
171 K: Borrow<Q>,
172 Q: ?Sized + Eq,
173 {
174 let mut probe = hash.desired_pos(Self::mask());
175 let mut dist = 0;
176
177 probe_loop!(probe < self.indices.len(), {
178 if let Some(pos) = self.indices[probe] {
179 let entry_hash = pos.hash();
180 // NOTE(i) we use unchecked indexing below
181 let i = pos.index();
182 debug_assert!(i < self.entries.len());
183
184 if dist > entry_hash.probe_distance(Self::mask(), probe) {
185 // give up when probe distance is too long
186 return None;
187 } else if entry_hash == hash
188 && unsafe { self.entries.get_unchecked(i).key.borrow() == query }
189 {
190 return Some((probe, i));
191 }
192 } else {
193 return None;
194 }
195
196 dist += 1;
197 });
198 }
199
200 fn insert(&mut self, hash: HashValue, key: K, value: V) -> Insert<K, V> {
201 let mut probe = hash.desired_pos(Self::mask());
202 let mut dist = 0;
203
204 probe_loop!(probe < self.indices.len(), {
205 let pos = &mut self.indices[probe];
206
207 if let Some(pos) = *pos {
208 let entry_hash = pos.hash();
209 // NOTE(i) we use unchecked indexing below
210 let i = pos.index();
211 debug_assert!(i < self.entries.len());
212
213 let their_dist = entry_hash.probe_distance(Self::mask(), probe);
214
215 if their_dist < dist {
216 if self.entries.is_full() {
217 return Insert::Full((key, value));
218 }
219 // robin hood: steal the spot if it's better for us
220 let index = self.entries.len();
221 unsafe { self.entries.push_unchecked(Bucket { hash, key, value }) };
222 Self::insert_phase_2(&mut self.indices, probe, Pos::new(index, hash));
223 return Insert::Success(Inserted {
224 index,
225 old_value: None,
226 });
227 } else if entry_hash == hash && unsafe { self.entries.get_unchecked(i).key == key }
228 {
229 return Insert::Success(Inserted {
230 index: i,
231 old_value: Some(mem::replace(
232 unsafe { &mut self.entries.get_unchecked_mut(i).value },
233 value,
234 )),
235 });
236 }
237 } else {
238 if self.entries.is_full() {
239 return Insert::Full((key, value));
240 }
241 // empty bucket, insert here
242 let index = self.entries.len();
243 *pos = Some(Pos::new(index, hash));
244 unsafe { self.entries.push_unchecked(Bucket { hash, key, value }) };
245 return Insert::Success(Inserted {
246 index,
247 old_value: None,
248 });
249 }
250 dist += 1;
251 });
252 }
253
254 // phase 2 is post-insert where we forward-shift `Pos` in the indices.
255 fn insert_phase_2(indices: &mut [Option<Pos>; N], mut probe: usize, mut old_pos: Pos) -> usize {
256 probe_loop!(probe < indices.len(), {
257 let pos = unsafe { indices.get_unchecked_mut(probe) };
258
259 let mut is_none = true; // work around lack of NLL
260 if let Some(pos) = pos.as_mut() {
261 old_pos = mem::replace(pos, old_pos);
262 is_none = false;
263 }
264
265 if is_none {
266 *pos = Some(old_pos);
267 return probe;
268 }
269 });
270 }
271
272 fn remove_found(&mut self, probe: usize, found: usize) -> (K, V) {
273 // index `probe` and entry `found` is to be removed
274 // use swap_remove, but then we need to update the index that points
275 // to the other entry that has to move
276 self.indices[probe] = None;
277 let entry = unsafe { self.entries.swap_remove_unchecked(found) };
278
279 // correct index that points to the entry that had to swap places
280 if let Some(entry) = self.entries.get(found) {
281 // was not last element
282 // examine new element in `found` and find it in indices
283 let mut probe = entry.hash.desired_pos(Self::mask());
284
285 probe_loop!(probe < self.indices.len(), {
286 if let Some(pos) = self.indices[probe] {
287 if pos.index() >= self.entries.len() {
288 // found it
289 self.indices[probe] = Some(Pos::new(found, entry.hash));
290 break;
291 }
292 }
293 });
294 }
295
296 self.backward_shift_after_removal(probe);
297
298 (entry.key, entry.value)
299 }
300
301 fn retain_in_order<F>(&mut self, mut keep: F)
302 where
303 F: FnMut(&mut K, &mut V) -> bool,
304 {
305 const INIT: Option<Pos> = None;
306
307 self.entries
308 .retain_mut(|entry| keep(&mut entry.key, &mut entry.value));
309
310 if self.entries.len() < self.indices.len() {
311 for index in self.indices.iter_mut() {
312 *index = INIT;
313 }
314
315 for (index, entry) in self.entries.iter().enumerate() {
316 let mut probe = entry.hash.desired_pos(Self::mask());
317 let mut dist = 0;
318
319 probe_loop!(probe < self.indices.len(), {
320 let pos = &mut self.indices[probe];
321
322 if let Some(pos) = *pos {
323 let entry_hash = pos.hash();
324
325 // robin hood: steal the spot if it's better for us
326 let their_dist = entry_hash.probe_distance(Self::mask(), probe);
327 if their_dist < dist {
328 Self::insert_phase_2(
329 &mut self.indices,
330 probe,
331 Pos::new(index, entry.hash),
332 );
333 break;
334 }
335 } else {
336 *pos = Some(Pos::new(index, entry.hash));
337 break;
338 }
339 dist += 1;
340 });
341 }
342 }
343 }
344
345 fn backward_shift_after_removal(&mut self, probe_at_remove: usize) {
346 // backward shift deletion in self.indices
347 // after probe, shift all non-ideally placed indices backward
348 let mut last_probe = probe_at_remove;
349 let mut probe = probe_at_remove + 1;
350
351 probe_loop!(probe < self.indices.len(), {
352 if let Some(pos) = self.indices[probe] {
353 let entry_hash = pos.hash();
354
355 if entry_hash.probe_distance(Self::mask(), probe) > 0 {
356 unsafe { *self.indices.get_unchecked_mut(last_probe) = self.indices[probe] }
357 self.indices[probe] = None;
358 } else {
359 break;
360 }
361 } else {
362 break;
363 }
364 last_probe = probe;
365 });
366 }
367}
368
369impl<K, V, const N: usize> Clone for CoreMap<K, V, N>
370where
371 K: Clone,
372 V: Clone,
373{
374 fn clone(&self) -> Self {
375 Self {
376 entries: self.entries.clone(),
377 indices: self.indices,
378 }
379 }
380}
381
382/// A view into an entry in the map
383pub enum Entry<'a, K, V, const N: usize> {
384 /// The entry corresponding to the key `K` exists in the map
385 Occupied(OccupiedEntry<'a, K, V, N>),
386 /// The entry corresponding to the key `K` does not exist in the map
387 Vacant(VacantEntry<'a, K, V, N>),
388}
389
390impl<'a, K, V, const N: usize> Entry<'a, K, V, N>
391where
392 K: Eq + Hash,
393{
394 /// Ensures a value is in the entry by inserting the default if empty, and
395 /// returns a mutable reference to the value in the entry.
396 ///
397 /// # Examples
398 ///
399 /// ```
400 /// use heapless::index_map::FnvIndexMap;
401 ///
402 /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
403 /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
404 /// let result = book_reviews
405 /// .entry("Adventures of Huckleberry Finn")
406 /// .or_insert("My favorite book.");
407 ///
408 /// assert_eq!(result, Ok(&mut "My favorite book."));
409 /// assert_eq!(
410 /// book_reviews["Adventures of Huckleberry Finn"],
411 /// "My favorite book."
412 /// );
413 /// ```
414 pub fn or_insert(self, default: V) -> Result<&'a mut V, V> {
415 match self {
416 Self::Occupied(entry) => Ok(entry.into_mut()),
417 Self::Vacant(entry) => entry.insert(default),
418 }
419 }
420
421 /// Ensures a value is in the entry by inserting the result of the default
422 /// function if empty, and returns a mutable reference to the value in the
423 /// entry.
424 ///
425 /// # Examples
426 ///
427 /// ```
428 /// use heapless::index_map::FnvIndexMap;
429 ///
430 /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
431 /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
432 /// let s = "Masterpiece.".to_string();
433 ///
434 /// book_reviews
435 /// .entry("Grimms' Fairy Tales")
436 /// .or_insert_with(|| s);
437 ///
438 /// assert_eq!(
439 /// book_reviews["Grimms' Fairy Tales"],
440 /// "Masterpiece.".to_string()
441 /// );
442 /// ```
443 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> Result<&'a mut V, V> {
444 match self {
445 Self::Occupied(entry) => Ok(entry.into_mut()),
446 Self::Vacant(entry) => entry.insert(default()),
447 }
448 }
449
450 /// Ensures a value is in the entry by inserting, if empty, the result of
451 /// the default function. This method allows for generating key-derived
452 /// values for insertion by providing the default function a reference to
453 /// the key that was moved during the `.entry(key)` method call.
454 ///
455 /// The reference to the moved key is provided so that cloning or copying
456 /// the key is unnecessary, unlike with `.or_insert_with(|| ... )`.
457 ///
458 /// # Examples
459 ///
460 /// ```
461 /// use heapless::index_map::FnvIndexMap;
462 ///
463 /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
464 /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
465 ///
466 /// book_reviews
467 /// .entry("Pride and Prejudice")
468 /// .or_insert_with_key(|key| key.chars().count());
469 ///
470 /// assert_eq!(book_reviews["Pride and Prejudice"], 19);
471 /// ```
472 pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> Result<&'a mut V, V> {
473 match self {
474 Self::Occupied(entry) => Ok(entry.into_mut()),
475 Self::Vacant(entry) => {
476 let value = default(entry.key());
477 entry.insert(value)
478 }
479 }
480 }
481
482 /// Returns a reference to this entry's key.
483 ///
484 /// # Examples
485 ///
486 /// ```
487 /// use heapless::index_map::FnvIndexMap;
488 ///
489 /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
490 /// let mut book_reviews = FnvIndexMap::<&str, &str, 16>::new();
491 /// assert_eq!(
492 /// book_reviews
493 /// .entry("The Adventures of Sherlock Holmes")
494 /// .key(),
495 /// &"The Adventures of Sherlock Holmes"
496 /// );
497 /// ```
498 pub fn key(&self) -> &K {
499 match *self {
500 Self::Occupied(ref entry) => entry.key(),
501 Self::Vacant(ref entry) => entry.key(),
502 }
503 }
504
505 /// Provides in-place mutable access to an occupied entry before any
506 /// potential inserts into the map.
507 ///
508 /// # Examples
509 ///
510 /// ```
511 /// use heapless::index_map::FnvIndexMap;
512 ///
513 /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
514 /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
515 ///
516 /// book_reviews
517 /// .entry("Grimms' Fairy Tales")
518 /// .and_modify(|e| *e = "Masterpiece.")
519 /// .or_insert("Very enjoyable.");
520 /// assert_eq!(book_reviews["Grimms' Fairy Tales"], "Very enjoyable.");
521 /// ```
522 pub fn and_modify<F>(self, f: F) -> Self
523 where
524 F: FnOnce(&mut V),
525 {
526 match self {
527 Self::Occupied(mut entry) => {
528 f(entry.get_mut());
529 Self::Occupied(entry)
530 }
531 Self::Vacant(entry) => Self::Vacant(entry),
532 }
533 }
534}
535
536impl<'a, K, V, const N: usize> Entry<'a, K, V, N>
537where
538 K: Eq + Hash,
539 V: Default,
540{
541 /// Ensures a value is in the entry by inserting the default value if empty,
542 /// and returns a mutable reference to the value in the entry.
543 ///
544 /// # Examples
545 ///
546 /// ```
547 /// # fn main() {
548 /// use heapless::index_map::FnvIndexMap;
549 ///
550 /// let mut book_reviews = FnvIndexMap::<&str, Option<&str>, 16>::new();
551 ///
552 /// book_reviews.entry("Pride and Prejudice").or_default();
553 ///
554 /// assert_eq!(book_reviews["Pride and Prejudice"], None);
555 /// # }
556 /// ```
557 #[inline]
558 pub fn or_default(self) -> Result<&'a mut V, V> {
559 match self {
560 Self::Occupied(entry) => Ok(entry.into_mut()),
561 Self::Vacant(entry) => entry.insert(Default::default()),
562 }
563 }
564}
565
566/// An occupied entry which can be manipulated
567pub struct OccupiedEntry<'a, K, V, const N: usize> {
568 key: K,
569 probe: usize,
570 pos: usize,
571 core: &'a mut CoreMap<K, V, N>,
572}
573
574impl<'a, K, V, const N: usize> OccupiedEntry<'a, K, V, N>
575where
576 K: Eq + Hash,
577{
578 /// Gets a reference to the key that this entity corresponds to
579 pub fn key(&self) -> &K {
580 &self.key
581 }
582
583 /// Removes this entry from the map and yields its corresponding key and value
584 pub fn remove_entry(self) -> (K, V) {
585 self.core.remove_found(self.probe, self.pos)
586 }
587
588 /// Gets a reference to the value associated with this entry
589 pub fn get(&self) -> &V {
590 // SAFETY: Already checked existence at instantiation and the only mutable reference
591 // to the map is internally held.
592 unsafe { &self.core.entries.get_unchecked(self.pos).value }
593 }
594
595 /// Gets a mutable reference to the value associated with this entry
596 pub fn get_mut(&mut self) -> &mut V {
597 // SAFETY: Already checked existence at instantiation and the only mutable reference
598 // to the map is internally held.
599 unsafe { &mut self.core.entries.get_unchecked_mut(self.pos).value }
600 }
601
602 /// Consumes this entry and yields a reference to the underlying value
603 pub fn into_mut(self) -> &'a mut V {
604 // SAFETY: Already checked existence at instantiation and the only mutable reference
605 // to the map is internally held.
606 unsafe { &mut self.core.entries.get_unchecked_mut(self.pos).value }
607 }
608
609 /// Overwrites the underlying map's value with this entry's value
610 pub fn insert(self, value: V) -> V {
611 // SAFETY: Already checked existence at instantiation and the only mutable reference
612 // to the map is internally held.
613 unsafe {
614 mem::replace(
615 &mut self.core.entries.get_unchecked_mut(self.pos).value,
616 value,
617 )
618 }
619 }
620
621 /// Removes this entry from the map and yields its value
622 pub fn remove(self) -> V {
623 self.remove_entry().1
624 }
625}
626
627/// A view into an empty slot in the underlying map
628pub struct VacantEntry<'a, K, V, const N: usize> {
629 key: K,
630 hash_val: HashValue,
631 core: &'a mut CoreMap<K, V, N>,
632}
633impl<'a, K, V, const N: usize> VacantEntry<'a, K, V, N>
634where
635 K: Eq + Hash,
636{
637 /// Get the key associated with this entry
638 pub fn key(&self) -> &K {
639 &self.key
640 }
641
642 /// Consumes this entry to yield to key associated with it
643 pub fn into_key(self) -> K {
644 self.key
645 }
646
647 /// Inserts this entry into to underlying map, yields a mutable reference to the inserted value.
648 /// If the map is at capacity the value is returned instead.
649 pub fn insert(self, value: V) -> Result<&'a mut V, V> {
650 if self.core.entries.is_full() {
651 Err(value)
652 } else {
653 match self.core.insert(self.hash_val, self.key, value) {
654 Insert::Success(inserted) => {
655 unsafe {
656 // SAFETY: Already checked existence at instantiation and the only mutable reference
657 // to the map is internally held.
658 Ok(&mut (*self.core.entries.as_mut_ptr().add(inserted.index)).value)
659 }
660 }
661 Insert::Full((_, v)) => Err(v),
662 }
663 }
664 }
665}
666
667/// Fixed capacity [`IndexMap`](https://docs.rs/indexmap/2/indexmap/map/struct.IndexMap.html)
668///
669/// Note that you cannot use `IndexMap` directly, since it is generic around the hashing algorithm
670/// in use. Pick a concrete instantiation like [`FnvIndexMap`] instead
671/// or create your own.
672///
673/// Note that the capacity of the `IndexMap` must be a power of 2.
674///
675/// # Examples
676///
677/// Since `IndexMap` cannot be used directly, we're using its `FnvIndexMap` instantiation
678/// for this example.
679///
680/// ```
681/// use heapless::index_map::FnvIndexMap;
682///
683/// // A hash map with a capacity of 16 key-value pairs allocated on the stack
684/// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
685///
686/// // review some books.
687/// book_reviews
688/// .insert("Adventures of Huckleberry Finn", "My favorite book.")
689/// .unwrap();
690/// book_reviews
691/// .insert("Grimms' Fairy Tales", "Masterpiece.")
692/// .unwrap();
693/// book_reviews
694/// .insert("Pride and Prejudice", "Very enjoyable.")
695/// .unwrap();
696/// book_reviews
697/// .insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.")
698/// .unwrap();
699///
700/// // check for a specific one.
701/// if !book_reviews.contains_key("Les Misérables") {
702/// println!(
703/// "We've got {} reviews, but Les Misérables ain't one.",
704/// book_reviews.len()
705/// );
706/// }
707///
708/// // oops, this review has a lot of spelling mistakes, let's delete it.
709/// book_reviews.remove("The Adventures of Sherlock Holmes");
710///
711/// // look up the values associated with some keys.
712/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
713/// for book in &to_find {
714/// match book_reviews.get(book) {
715/// Some(review) => println!("{}: {}", book, review),
716/// None => println!("{} is unreviewed.", book),
717/// }
718/// }
719///
720/// // iterate over everything.
721/// for (book, review) in &book_reviews {
722/// println!("{}: \"{}\"", book, review);
723/// }
724/// ```
725pub struct IndexMap<K, V, S, const N: usize> {
726 core: CoreMap<K, V, N>,
727 build_hasher: S,
728}
729
730impl<K, V, S, const N: usize> IndexMap<K, V, BuildHasherDefault<S>, N> {
731 /// Creates an empty `IndexMap`.
732 pub const fn new() -> Self {
733 const {
734 assert!(N > 1);
735 assert!(N.is_power_of_two());
736 }
737
738 Self {
739 build_hasher: BuildHasherDefault::new(),
740 core: CoreMap::new(),
741 }
742 }
743}
744
745impl<K, V, S, const N: usize> IndexMap<K, V, S, N> {
746 /// Returns the number of elements the map can hold
747 pub fn capacity(&self) -> usize {
748 N
749 }
750
751 /// Return an iterator over the keys of the map, in insertion order
752 ///
753 /// ```
754 /// use heapless::index_map::FnvIndexMap;
755 ///
756 /// let mut map = FnvIndexMap::<_, _, 16>::new();
757 /// map.insert("a", 1).unwrap();
758 /// map.insert("b", 2).unwrap();
759 /// map.insert("c", 3).unwrap();
760 ///
761 /// for key in map.keys() {
762 /// println!("{}", key);
763 /// }
764 /// ```
765 pub fn keys(&self) -> Keys<'_, K, V> {
766 Keys {
767 iter: self.core.entries.iter(),
768 }
769 }
770
771 /// Return an iterator over the values of the map, in insertion order
772 ///
773 /// ```
774 /// use heapless::index_map::FnvIndexMap;
775 ///
776 /// let mut map = FnvIndexMap::<_, _, 16>::new();
777 /// map.insert("a", 1).unwrap();
778 /// map.insert("b", 2).unwrap();
779 /// map.insert("c", 3).unwrap();
780 ///
781 /// for val in map.values() {
782 /// println!("{}", val);
783 /// }
784 /// ```
785 pub fn values(&self) -> Values<'_, K, V> {
786 Values {
787 iter: self.core.entries.iter(),
788 }
789 }
790
791 /// Return an iterator over mutable references to the the values of the map, in insertion order
792 ///
793 /// ```
794 /// use heapless::index_map::FnvIndexMap;
795 ///
796 /// let mut map = FnvIndexMap::<_, _, 16>::new();
797 /// map.insert("a", 1).unwrap();
798 /// map.insert("b", 2).unwrap();
799 /// map.insert("c", 3).unwrap();
800 ///
801 /// for val in map.values_mut() {
802 /// *val += 10;
803 /// }
804 ///
805 /// for val in map.values() {
806 /// println!("{}", val);
807 /// }
808 /// ```
809 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
810 ValuesMut {
811 iter: self.core.entries.iter_mut(),
812 }
813 }
814
815 /// Return an iterator over the key-value pairs of the map, in insertion order
816 ///
817 /// ```
818 /// use heapless::index_map::FnvIndexMap;
819 ///
820 /// let mut map = FnvIndexMap::<_, _, 16>::new();
821 /// map.insert("a", 1).unwrap();
822 /// map.insert("b", 2).unwrap();
823 /// map.insert("c", 3).unwrap();
824 ///
825 /// for (key, val) in map.iter() {
826 /// println!("key: {} val: {}", key, val);
827 /// }
828 /// ```
829 pub fn iter(&self) -> Iter<'_, K, V> {
830 Iter {
831 iter: self.core.entries.iter(),
832 }
833 }
834
835 /// Return an iterator over the key-value pairs of the map, in insertion order
836 ///
837 /// ```
838 /// use heapless::index_map::FnvIndexMap;
839 ///
840 /// let mut map = FnvIndexMap::<_, _, 16>::new();
841 /// map.insert("a", 1).unwrap();
842 /// map.insert("b", 2).unwrap();
843 /// map.insert("c", 3).unwrap();
844 ///
845 /// for (_, val) in map.iter_mut() {
846 /// *val = 2;
847 /// }
848 ///
849 /// for (key, val) in &map {
850 /// println!("key: {} val: {}", key, val);
851 /// }
852 /// ```
853 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
854 IterMut {
855 iter: self.core.entries.iter_mut(),
856 }
857 }
858
859 /// Get the first key-value pair
860 ///
861 /// Computes in *O*(1) time
862 pub fn first(&self) -> Option<(&K, &V)> {
863 self.core
864 .entries
865 .first()
866 .map(|bucket| (&bucket.key, &bucket.value))
867 }
868
869 /// Get the first key-value pair, with mutable access to the value
870 ///
871 /// Computes in *O*(1) time
872 pub fn first_mut(&mut self) -> Option<(&K, &mut V)> {
873 self.core
874 .entries
875 .first_mut()
876 .map(|bucket| (&bucket.key, &mut bucket.value))
877 }
878
879 /// Get the last key-value pair
880 ///
881 /// Computes in *O*(1) time
882 pub fn last(&self) -> Option<(&K, &V)> {
883 self.core
884 .entries
885 .last()
886 .map(|bucket| (&bucket.key, &bucket.value))
887 }
888
889 /// Get the last key-value pair, with mutable access to the value
890 ///
891 /// Computes in *O*(1) time
892 pub fn last_mut(&mut self) -> Option<(&K, &mut V)> {
893 self.core
894 .entries
895 .last_mut()
896 .map(|bucket| (&bucket.key, &mut bucket.value))
897 }
898
899 /// Return the number of key-value pairs in the map.
900 ///
901 /// Computes in *O*(1) time.
902 ///
903 /// ```
904 /// use heapless::index_map::FnvIndexMap;
905 ///
906 /// let mut a = FnvIndexMap::<_, _, 16>::new();
907 /// assert_eq!(a.len(), 0);
908 /// a.insert(1, "a").unwrap();
909 /// assert_eq!(a.len(), 1);
910 /// ```
911 pub fn len(&self) -> usize {
912 self.core.entries.len()
913 }
914
915 /// Returns true if the map contains no elements.
916 ///
917 /// Computes in *O*(1) time.
918 ///
919 /// ```
920 /// use heapless::index_map::FnvIndexMap;
921 ///
922 /// let mut a = FnvIndexMap::<_, _, 16>::new();
923 /// assert!(a.is_empty());
924 /// a.insert(1, "a");
925 /// assert!(!a.is_empty());
926 /// ```
927 pub fn is_empty(&self) -> bool {
928 self.len() == 0
929 }
930
931 /// Returns true if the map is full.
932 ///
933 /// Computes in *O*(1) time.
934 ///
935 /// ```
936 /// use heapless::index_map::FnvIndexMap;
937 ///
938 /// let mut a = FnvIndexMap::<_, _, 4>::new();
939 /// assert!(!a.is_full());
940 /// a.insert(1, "a");
941 /// a.insert(2, "b");
942 /// a.insert(3, "c");
943 /// a.insert(4, "d");
944 /// assert!(a.is_full());
945 /// ```
946 pub fn is_full(&self) -> bool {
947 self.len() == self.capacity()
948 }
949
950 /// Remove all key-value pairs in the map, while preserving its capacity.
951 ///
952 /// Computes in *O*(n) time.
953 ///
954 /// ```
955 /// use heapless::index_map::FnvIndexMap;
956 ///
957 /// let mut a = FnvIndexMap::<_, _, 16>::new();
958 /// a.insert(1, "a");
959 /// a.clear();
960 /// assert!(a.is_empty());
961 /// ```
962 pub fn clear(&mut self) {
963 self.core.entries.clear();
964 for pos in self.core.indices.iter_mut() {
965 *pos = None;
966 }
967 }
968}
969
970impl<K, V, S, const N: usize> IndexMap<K, V, S, N>
971where
972 K: Eq + Hash,
973 S: BuildHasher,
974{
975 /* Public API */
976 /// Returns an entry for the corresponding key
977 /// ```
978 /// use heapless::index_map::Entry;
979 /// use heapless::index_map::FnvIndexMap;
980 /// let mut map = FnvIndexMap::<_, _, 16>::new();
981 /// if let Entry::Vacant(v) = map.entry("a") {
982 /// v.insert(1).unwrap();
983 /// }
984 /// if let Entry::Occupied(mut o) = map.entry("a") {
985 /// println!("found {}", *o.get()); // Prints 1
986 /// o.insert(2);
987 /// }
988 /// // Prints 2
989 /// println!("val: {}", *map.get("a").unwrap());
990 /// ```
991 pub fn entry(&mut self, key: K) -> Entry<'_, K, V, N> {
992 let hash_val = hash_with(&key, &self.build_hasher);
993 if let Some((probe, pos)) = self.core.find(hash_val, &key) {
994 Entry::Occupied(OccupiedEntry {
995 key,
996 probe,
997 pos,
998 core: &mut self.core,
999 })
1000 } else {
1001 Entry::Vacant(VacantEntry {
1002 key,
1003 hash_val,
1004 core: &mut self.core,
1005 })
1006 }
1007 }
1008
1009 /// Returns a reference to the value corresponding to the key.
1010 ///
1011 /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1012 /// form *must* match those for the key type.
1013 ///
1014 /// Computes in *O*(1) time (average).
1015 ///
1016 /// ```
1017 /// use heapless::index_map::FnvIndexMap;
1018 ///
1019 /// let mut map = FnvIndexMap::<_, _, 16>::new();
1020 /// map.insert(1, "a").unwrap();
1021 /// assert_eq!(map.get(&1), Some(&"a"));
1022 /// assert_eq!(map.get(&2), None);
1023 /// ```
1024 pub fn get<Q>(&self, key: &Q) -> Option<&V>
1025 where
1026 K: Borrow<Q>,
1027 Q: ?Sized + Hash + Eq,
1028 {
1029 self.find(key)
1030 .map(|(_, found)| unsafe { &self.core.entries.get_unchecked(found).value })
1031 }
1032
1033 /// Returns true if the map contains a value for the specified key.
1034 ///
1035 /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1036 /// form *must* match those for the key type.
1037 ///
1038 /// Computes in *O*(1) time (average).
1039 ///
1040 /// # Examples
1041 ///
1042 /// ```
1043 /// use heapless::index_map::FnvIndexMap;
1044 ///
1045 /// let mut map = FnvIndexMap::<_, _, 8>::new();
1046 /// map.insert(1, "a").unwrap();
1047 /// assert_eq!(map.contains_key(&1), true);
1048 /// assert_eq!(map.contains_key(&2), false);
1049 /// ```
1050 pub fn contains_key<Q>(&self, key: &Q) -> bool
1051 where
1052 K: Borrow<Q>,
1053 Q: ?Sized + Eq + Hash,
1054 {
1055 self.find(key).is_some()
1056 }
1057
1058 /// Returns a mutable reference to the value corresponding to the key.
1059 ///
1060 /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1061 /// form *must* match those for the key type.
1062 ///
1063 /// Computes in *O*(1) time (average).
1064 ///
1065 /// # Examples
1066 ///
1067 /// ```
1068 /// use heapless::index_map::FnvIndexMap;
1069 ///
1070 /// let mut map = FnvIndexMap::<_, _, 8>::new();
1071 /// map.insert(1, "a").unwrap();
1072 /// if let Some(x) = map.get_mut(&1) {
1073 /// *x = "b";
1074 /// }
1075 /// assert_eq!(map[&1], "b");
1076 /// ```
1077 pub fn get_mut<'v, Q>(&'v mut self, key: &Q) -> Option<&'v mut V>
1078 where
1079 K: Borrow<Q>,
1080 Q: ?Sized + Hash + Eq,
1081 {
1082 if let Some((_, found)) = self.find(key) {
1083 Some(unsafe { &mut self.core.entries.get_unchecked_mut(found).value })
1084 } else {
1085 None
1086 }
1087 }
1088
1089 /// Returns a tuple of references to the key and the value corresponding to the index.
1090 ///
1091 /// Computes in *O*(1) time (average).
1092 ///
1093 /// # Examples
1094 ///
1095 /// ```
1096 /// use heapless::index_map::FnvIndexMap;
1097 ///
1098 /// let mut map = FnvIndexMap::<_, _, 16>::new();
1099 /// map.insert(1, "a").unwrap();
1100 /// assert_eq!(map.get_index(0), Some((&1, &"a")));
1101 /// assert_eq!(map.get_index(1), None);
1102 /// ```
1103 pub fn get_index(&self, index: usize) -> Option<(&K, &V)> {
1104 self.core
1105 .entries
1106 .get(index)
1107 .map(|entry| (&entry.key, &entry.value))
1108 }
1109
1110 /// Returns a tuple of references to the key and the mutable value corresponding to the index.
1111 ///
1112 /// Computes in *O*(1) time (average).
1113 ///
1114 /// # Examples
1115 ///
1116 /// ```
1117 /// use heapless::index_map::FnvIndexMap;
1118 ///
1119 /// let mut map = FnvIndexMap::<_, _, 8>::new();
1120 /// map.insert(1, "a").unwrap();
1121 /// if let Some((_, x)) = map.get_index_mut(0) {
1122 /// *x = "b";
1123 /// }
1124 /// assert_eq!(map[&1], "b");
1125 /// ```
1126 pub fn get_index_mut(&mut self, index: usize) -> Option<(&K, &mut V)> {
1127 self.core
1128 .entries
1129 .get_mut(index)
1130 .map(|entry| (&entry.key, &mut entry.value))
1131 }
1132
1133 /// Returns the index of the key-value pair corresponding to the key.
1134 ///
1135 /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1136 /// form *must* match those for the key type.
1137 ///
1138 /// Computes in *O*(1) time (average).
1139 ///
1140 /// # Examples
1141 ///
1142 /// ```
1143 /// use heapless::index_map::FnvIndexMap;
1144 ///
1145 /// let mut map = FnvIndexMap::<_, _, 8>::new();
1146 /// map.insert(1, "a").unwrap();
1147 /// map.insert(0, "b").unwrap();
1148 /// assert_eq!(map.get_index_of(&0), Some(1));
1149 /// assert_eq!(map.get_index_of(&1), Some(0));
1150 /// assert_eq!(map.get_index_of(&2), None);
1151 /// ```
1152 pub fn get_index_of<Q>(&self, key: &Q) -> Option<usize>
1153 where
1154 K: Borrow<Q>,
1155 Q: ?Sized + Hash + Eq,
1156 {
1157 self.find(key).map(|(_, found)| found)
1158 }
1159
1160 /// Inserts a key-value pair into the map.
1161 ///
1162 /// If an equivalent key already exists in the map: the key remains and retains in its place in
1163 /// the order, its corresponding value is updated with `value` and the older value is returned
1164 /// inside `Some(_)`.
1165 ///
1166 /// If no equivalent key existed in the map: the new key-value pair is inserted, last in order,
1167 /// and `None` is returned.
1168 ///
1169 /// Computes in *O*(1) time (average).
1170 ///
1171 /// See also entry if you you want to insert or modify or if you need to get the index of the
1172 /// corresponding key-value pair.
1173 ///
1174 /// # Examples
1175 ///
1176 /// ```
1177 /// use heapless::index_map::FnvIndexMap;
1178 ///
1179 /// let mut map = FnvIndexMap::<_, _, 8>::new();
1180 /// assert_eq!(map.insert(37, "a"), Ok(None));
1181 /// assert_eq!(map.is_empty(), false);
1182 ///
1183 /// map.insert(37, "b");
1184 /// assert_eq!(map.insert(37, "c"), Ok(Some("b")));
1185 /// assert_eq!(map[&37], "c");
1186 /// ```
1187 pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V)> {
1188 let hash = hash_with(&key, &self.build_hasher);
1189 match self.core.insert(hash, key, value) {
1190 Insert::Success(inserted) => Ok(inserted.old_value),
1191 Insert::Full((k, v)) => Err((k, v)),
1192 }
1193 }
1194
1195 /// Same as [`swap_remove`](Self::swap_remove)
1196 ///
1197 /// Computes in *O*(1) time (average).
1198 ///
1199 /// # Examples
1200 ///
1201 /// ```
1202 /// use heapless::index_map::FnvIndexMap;
1203 ///
1204 /// let mut map = FnvIndexMap::<_, _, 8>::new();
1205 /// map.insert(1, "a").unwrap();
1206 /// assert_eq!(map.remove(&1), Some("a"));
1207 /// assert_eq!(map.remove(&1), None);
1208 /// ```
1209 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
1210 where
1211 K: Borrow<Q>,
1212 Q: ?Sized + Hash + Eq,
1213 {
1214 self.swap_remove(key)
1215 }
1216
1217 /// Remove the key-value pair equivalent to `key` and return its value.
1218 ///
1219 /// Like `Vec::swap_remove`, the pair is removed by swapping it with the last element of the map
1220 /// and popping it off. **This perturbs the position of what used to be the last element!**
1221 ///
1222 /// Return `None` if `key` is not in map.
1223 ///
1224 /// Computes in *O*(1) time (average).
1225 pub fn swap_remove<Q>(&mut self, key: &Q) -> Option<V>
1226 where
1227 K: Borrow<Q>,
1228 Q: ?Sized + Hash + Eq,
1229 {
1230 self.find(key)
1231 .map(|(probe, found)| self.core.remove_found(probe, found).1)
1232 }
1233
1234 /// Retains only the elements specified by the predicate.
1235 ///
1236 /// In other words, remove all pairs `(k, v)` for which `f(&k, &mut v)` returns `false`.
1237 pub fn retain<F>(&mut self, mut f: F)
1238 where
1239 F: FnMut(&K, &mut V) -> bool,
1240 {
1241 self.core.retain_in_order(move |k, v| f(k, v));
1242 }
1243
1244 /// Shortens the map, keeping the first `len` elements and dropping the rest.
1245 ///
1246 /// If `len` is greater than the map's current length, this has no effect.
1247 ///
1248 /// Computes in *O*(n) time (average).
1249 ///
1250 /// # Examples
1251 ///
1252 /// ```
1253 /// use heapless::index_map::FnvIndexMap;
1254 ///
1255 /// let mut map = FnvIndexMap::<_, _, 8>::new();
1256 /// map.insert(3, "a").unwrap();
1257 /// map.insert(2, "b").unwrap();
1258 /// map.insert(1, "c").unwrap();
1259 /// map.truncate(2);
1260 /// assert_eq!(map.len(), 2);
1261 /// assert_eq!(map.get(&1), None);
1262 ///
1263 /// let mut iter = map.iter();
1264 /// assert_eq!(iter.next(), Some((&3, &"a")));
1265 /// assert_eq!(iter.next(), Some((&2, &"b")));
1266 /// assert_eq!(iter.next(), None);
1267 /// ```
1268 pub fn truncate(&mut self, len: usize) {
1269 self.core.entries.truncate(len);
1270
1271 if self.core.indices.len() > self.core.entries.len() {
1272 for index in self.core.indices.iter_mut() {
1273 match index {
1274 Some(pos) if pos.index() >= len => *index = None,
1275 _ => (),
1276 }
1277 }
1278 }
1279 }
1280
1281 /* Private API */
1282 /// Return probe (indices) and position (entries)
1283 fn find<Q>(&self, key: &Q) -> Option<(usize, usize)>
1284 where
1285 K: Borrow<Q>,
1286 Q: ?Sized + Hash + Eq,
1287 {
1288 if self.is_empty() {
1289 return None;
1290 }
1291 let h = hash_with(key, &self.build_hasher);
1292 self.core.find(h, key)
1293 }
1294}
1295
1296impl<K, Q, V, S, const N: usize> ops::Index<&Q> for IndexMap<K, V, S, N>
1297where
1298 K: Eq + Hash + Borrow<Q>,
1299 Q: ?Sized + Eq + Hash,
1300 S: BuildHasher,
1301{
1302 type Output = V;
1303
1304 fn index(&self, key: &Q) -> &V {
1305 self.get(key).expect("key not found")
1306 }
1307}
1308
1309impl<K, Q, V, S, const N: usize> ops::IndexMut<&Q> for IndexMap<K, V, S, N>
1310where
1311 K: Eq + Hash + Borrow<Q>,
1312 Q: ?Sized + Eq + Hash,
1313 S: BuildHasher,
1314{
1315 fn index_mut(&mut self, key: &Q) -> &mut V {
1316 self.get_mut(key).expect("key not found")
1317 }
1318}
1319
1320impl<K, V, S, const N: usize> Clone for IndexMap<K, V, S, N>
1321where
1322 K: Clone,
1323 V: Clone,
1324 S: Clone,
1325{
1326 fn clone(&self) -> Self {
1327 Self {
1328 core: self.core.clone(),
1329 build_hasher: self.build_hasher.clone(),
1330 }
1331 }
1332}
1333
1334impl<K, V, S, const N: usize> fmt::Debug for IndexMap<K, V, S, N>
1335where
1336 K: fmt::Debug,
1337 V: fmt::Debug,
1338{
1339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1340 f.debug_map().entries(self.iter()).finish()
1341 }
1342}
1343
1344impl<K, V, S, const N: usize> Default for IndexMap<K, V, S, N>
1345where
1346 S: Default,
1347{
1348 fn default() -> Self {
1349 const {
1350 assert!(N > 1);
1351 assert!(N.is_power_of_two());
1352 }
1353
1354 Self {
1355 build_hasher: <_>::default(),
1356 core: CoreMap::new(),
1357 }
1358 }
1359}
1360
1361impl<K, V1, V2, S1, S2, const N1: usize, const N2: usize> PartialEq<IndexMap<K, V2, S2, N2>>
1362 for IndexMap<K, V1, S1, N1>
1363where
1364 K: Eq + Hash,
1365 V1: PartialEq<V2>,
1366 S1: BuildHasher,
1367 S2: BuildHasher,
1368{
1369 fn eq(&self, other: &IndexMap<K, V2, S2, N2>) -> bool {
1370 self.len() == other.len()
1371 && self
1372 .iter()
1373 .all(|(key, value)| other.get(key).is_some_and(|v| *value == *v))
1374 }
1375}
1376
1377impl<K, V, S, const N: usize> Eq for IndexMap<K, V, S, N>
1378where
1379 K: Eq + Hash,
1380 V: Eq,
1381 S: BuildHasher,
1382{
1383}
1384
1385impl<K, V, S, const N: usize> Extend<(K, V)> for IndexMap<K, V, S, N>
1386where
1387 K: Eq + Hash,
1388 S: BuildHasher,
1389{
1390 fn extend<I>(&mut self, iterable: I)
1391 where
1392 I: IntoIterator<Item = (K, V)>,
1393 {
1394 for (k, v) in iterable {
1395 self.insert(k, v).ok().unwrap();
1396 }
1397 }
1398}
1399
1400impl<'a, K, V, S, const N: usize> Extend<(&'a K, &'a V)> for IndexMap<K, V, S, N>
1401where
1402 K: Eq + Hash + Copy,
1403 V: Copy,
1404 S: BuildHasher,
1405{
1406 fn extend<I>(&mut self, iterable: I)
1407 where
1408 I: IntoIterator<Item = (&'a K, &'a V)>,
1409 {
1410 self.extend(iterable.into_iter().map(|(&key, &value)| (key, value)));
1411 }
1412}
1413
1414impl<K, V, S, const N: usize> FromIterator<(K, V)> for IndexMap<K, V, S, N>
1415where
1416 K: Eq + Hash,
1417 S: BuildHasher + Default,
1418{
1419 fn from_iter<I>(iterable: I) -> Self
1420 where
1421 I: IntoIterator<Item = (K, V)>,
1422 {
1423 let mut map = Self::default();
1424 map.extend(iterable);
1425 map
1426 }
1427}
1428
1429/// An owning iterator over the entries of an `IndexMap`.
1430///
1431/// This `struct` is created by the [`into_iter`] method on [`IndexMap`]
1432/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1433///
1434/// [`into_iter`]: IntoIterator::into_iter
1435///
1436/// # Example
1437///
1438/// ```
1439/// use heapless::index_map::FnvIndexMap;
1440///
1441/// let mut map = FnvIndexMap::<_, _, 16>::new();
1442/// map.insert("a", 1).unwrap();
1443///
1444/// let iter = map.into_iter();
1445/// ```
1446#[derive(Clone)]
1447pub struct IntoIter<K, V, const N: usize> {
1448 entries: Vec<Bucket<K, V>, N, usize>,
1449}
1450
1451impl<K, V, const N: usize> Iterator for IntoIter<K, V, N> {
1452 type Item = (K, V);
1453
1454 fn next(&mut self) -> Option<Self::Item> {
1455 self.entries.pop().map(|bucket| (bucket.key, bucket.value))
1456 }
1457}
1458
1459impl<K, V, S, const N: usize> IntoIterator for IndexMap<K, V, S, N> {
1460 type Item = (K, V);
1461 type IntoIter = IntoIter<K, V, N>;
1462
1463 fn into_iter(self) -> Self::IntoIter {
1464 IntoIter {
1465 entries: self.core.entries,
1466 }
1467 }
1468}
1469
1470impl<'a, K, V, S, const N: usize> IntoIterator for &'a IndexMap<K, V, S, N> {
1471 type Item = (&'a K, &'a V);
1472 type IntoIter = Iter<'a, K, V>;
1473
1474 fn into_iter(self) -> Self::IntoIter {
1475 self.iter()
1476 }
1477}
1478
1479impl<'a, K, V, S, const N: usize> IntoIterator for &'a mut IndexMap<K, V, S, N> {
1480 type Item = (&'a K, &'a mut V);
1481 type IntoIter = IterMut<'a, K, V>;
1482
1483 fn into_iter(self) -> Self::IntoIter {
1484 self.iter_mut()
1485 }
1486}
1487
1488/// An iterator over the items of a [`IndexMap`].
1489///
1490/// This `struct` is created by the [`iter`](IndexMap::iter) method on [`IndexMap`]. See its
1491/// documentation for more.
1492pub struct Iter<'a, K, V> {
1493 iter: slice::Iter<'a, Bucket<K, V>>,
1494}
1495
1496impl<'a, K, V> Iterator for Iter<'a, K, V> {
1497 type Item = (&'a K, &'a V);
1498
1499 fn next(&mut self) -> Option<Self::Item> {
1500 self.iter.next().map(|bucket| (&bucket.key, &bucket.value))
1501 }
1502}
1503
1504impl<K, V> Clone for Iter<'_, K, V> {
1505 fn clone(&self) -> Self {
1506 Self {
1507 iter: self.iter.clone(),
1508 }
1509 }
1510}
1511
1512/// A mutable iterator over the items of a [`IndexMap`].
1513///
1514/// This `struct` is created by the [`iter_mut`](IndexMap::iter_mut) method on [`IndexMap`]. See its
1515/// documentation for more.
1516pub struct IterMut<'a, K, V> {
1517 iter: slice::IterMut<'a, Bucket<K, V>>,
1518}
1519
1520impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1521 type Item = (&'a K, &'a mut V);
1522
1523 fn next(&mut self) -> Option<Self::Item> {
1524 self.iter
1525 .next()
1526 .map(|bucket| (&bucket.key, &mut bucket.value))
1527 }
1528}
1529
1530/// An iterator over the keys of a [`IndexMap`].
1531///
1532/// This `struct` is created by the [`keys`](IndexMap::keys) method on [`IndexMap`]. See its
1533/// documentation for more.
1534pub struct Keys<'a, K, V> {
1535 iter: slice::Iter<'a, Bucket<K, V>>,
1536}
1537
1538impl<'a, K, V> Iterator for Keys<'a, K, V> {
1539 type Item = &'a K;
1540
1541 fn next(&mut self) -> Option<Self::Item> {
1542 self.iter.next().map(|bucket| &bucket.key)
1543 }
1544}
1545
1546/// An iterator over the values of a [`IndexMap`].
1547///
1548/// This `struct` is created by the [`values`](IndexMap::values) method on [`IndexMap`]. See its
1549/// documentation for more.
1550pub struct Values<'a, K, V> {
1551 iter: slice::Iter<'a, Bucket<K, V>>,
1552}
1553
1554impl<'a, K, V> Iterator for Values<'a, K, V> {
1555 type Item = &'a V;
1556
1557 fn next(&mut self) -> Option<Self::Item> {
1558 self.iter.next().map(|bucket| &bucket.value)
1559 }
1560}
1561
1562/// A mutable iterator over the values of a [`IndexMap`].
1563///
1564/// This `struct` is created by the [`values_mut`](IndexMap::values_mut) method on [`IndexMap`]. See its
1565/// documentation for more.
1566pub struct ValuesMut<'a, K, V> {
1567 iter: slice::IterMut<'a, Bucket<K, V>>,
1568}
1569
1570impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
1571 type Item = &'a mut V;
1572
1573 fn next(&mut self) -> Option<Self::Item> {
1574 self.iter.next().map(|bucket| &mut bucket.value)
1575 }
1576}
1577
1578fn hash_with<K, S>(key: &K, build_hasher: &S) -> HashValue
1579where
1580 K: ?Sized + Hash,
1581 S: BuildHasher,
1582{
1583 HashValue(build_hasher.hash_one(key) as u16)
1584}
1585
1586#[cfg(test)]
1587mod tests {
1588 use core::mem;
1589
1590 use static_assertions::assert_not_impl_any;
1591
1592 use super::{BuildHasherDefault, Entry, FnvIndexMap, IndexMap};
1593
1594 // Ensure a `IndexMap` containing `!Send` keys stays `!Send` itself.
1595 assert_not_impl_any!(IndexMap<*const (), (), BuildHasherDefault<()>, 4>: Send);
1596 // Ensure a `IndexMap` containing `!Send` values stays `!Send` itself.
1597 assert_not_impl_any!(IndexMap<(), *const (), BuildHasherDefault<()>, 4>: Send);
1598
1599 #[test]
1600 fn size() {
1601 const CAP: usize = 4;
1602 assert_eq!(
1603 mem::size_of::<FnvIndexMap<i16, u16, CAP>>(),
1604 CAP * mem::size_of::<u32>() + // indices
1605 CAP * (mem::size_of::<i16>() + // key
1606 mem::size_of::<u16>() + // value
1607 mem::size_of::<u16>() // hash
1608 ) + // buckets
1609 mem::size_of::<usize>() // entries.length
1610 );
1611 }
1612
1613 #[test]
1614 fn partial_eq() {
1615 {
1616 let mut a: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1617 a.insert("k1", "v1").unwrap();
1618
1619 let mut b: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1620 b.insert("k1", "v1").unwrap();
1621
1622 assert!(a == b);
1623
1624 b.insert("k2", "v2").unwrap();
1625
1626 assert!(a != b);
1627 }
1628
1629 {
1630 let mut a: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1631 a.insert("k1", "v1").unwrap();
1632 a.insert("k2", "v2").unwrap();
1633
1634 let mut b: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1635 b.insert("k2", "v2").unwrap();
1636 b.insert("k1", "v1").unwrap();
1637
1638 assert!(a == b);
1639 }
1640 }
1641
1642 #[test]
1643 fn entry_or_insert() {
1644 let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1645 a.entry("k1").or_insert("v1").unwrap();
1646 assert_eq!(a["k1"], "v1");
1647
1648 a.entry("k2").or_insert("v2").unwrap();
1649 assert_eq!(a["k2"], "v2");
1650
1651 let result = a.entry("k3").or_insert("v3");
1652 assert_eq!(result, Err("v3"));
1653 }
1654
1655 #[test]
1656 fn entry_or_insert_with() {
1657 let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1658 a.entry("k1").or_insert_with(|| "v1").unwrap();
1659 assert_eq!(a["k1"], "v1");
1660
1661 a.entry("k2").or_insert_with(|| "v2").unwrap();
1662 assert_eq!(a["k2"], "v2");
1663
1664 let result = a.entry("k3").or_insert_with(|| "v3");
1665 assert_eq!(result, Err("v3"));
1666 }
1667
1668 #[test]
1669 fn entry_or_insert_with_key() {
1670 let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1671 a.entry("k1")
1672 .or_insert_with_key(|key| key.chars().count())
1673 .unwrap();
1674 assert_eq!(a["k1"], 2);
1675
1676 a.entry("k22")
1677 .or_insert_with_key(|key| key.chars().count())
1678 .unwrap();
1679 assert_eq!(a["k22"], 3);
1680
1681 let result = a.entry("k3").or_insert_with_key(|key| key.chars().count());
1682 assert_eq!(result, Err(2));
1683 }
1684
1685 #[test]
1686 fn entry_key() {
1687 let mut a: FnvIndexMap<&str, &str, 2> = FnvIndexMap::new();
1688
1689 assert_eq!(a.entry("k1").key(), &"k1");
1690 }
1691
1692 #[test]
1693 fn entry_and_modify() {
1694 let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1695 a.insert("k1", "v1").unwrap();
1696 a.entry("k1").and_modify(|e| *e = "modified v1");
1697
1698 assert_eq!(a["k1"], "modified v1");
1699
1700 a.entry("k2")
1701 .and_modify(|e| *e = "v2")
1702 .or_insert("default v2")
1703 .unwrap();
1704
1705 assert_eq!(a["k2"], "default v2");
1706 }
1707
1708 #[test]
1709 fn entry_or_default() {
1710 let mut a: FnvIndexMap<&str, Option<u32>, 2> = FnvIndexMap::new();
1711 a.entry("k1").or_default().unwrap();
1712
1713 assert_eq!(a["k1"], None);
1714
1715 let mut b: FnvIndexMap<&str, u8, 2> = FnvIndexMap::new();
1716 b.entry("k2").or_default().unwrap();
1717
1718 assert_eq!(b["k2"], 0);
1719 }
1720
1721 #[test]
1722 fn into_iter() {
1723 let mut src: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1724 src.insert("k1", "v1").unwrap();
1725 src.insert("k2", "v2").unwrap();
1726 src.insert("k3", "v3").unwrap();
1727 src.insert("k4", "v4").unwrap();
1728 let clone = src.clone();
1729 for (k, v) in clone.into_iter() {
1730 assert_eq!(v, *src.get(k).unwrap());
1731 }
1732 }
1733
1734 #[test]
1735 fn insert_replaces_on_full_map() {
1736 let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1737 a.insert("k1", "v1").unwrap();
1738 a.insert("k2", "v2").unwrap();
1739 a.insert("k1", "v2").unwrap();
1740 assert_eq!(a.get("k1"), a.get("k2"));
1741 }
1742
1743 // tests that use this constant take too long to run under miri, specially on CI, with a map of
1744 // this size so make the map smaller when using miri
1745 #[cfg(not(miri))]
1746 const MAP_SLOTS: usize = 4096;
1747 #[cfg(miri)]
1748 const MAP_SLOTS: usize = 64;
1749 fn almost_filled_map() -> FnvIndexMap<usize, usize, MAP_SLOTS> {
1750 let mut almost_filled = FnvIndexMap::new();
1751 for i in 1..MAP_SLOTS {
1752 almost_filled.insert(i, i).unwrap();
1753 }
1754 almost_filled
1755 }
1756
1757 #[test]
1758 fn entry_find() {
1759 let key = 0;
1760 let value = 0;
1761 let mut src = almost_filled_map();
1762 let entry = src.entry(key);
1763 match entry {
1764 Entry::Occupied(_) => {
1765 panic!("Found entry without inserting");
1766 }
1767 Entry::Vacant(v) => {
1768 assert_eq!(&key, v.key());
1769 assert_eq!(key, v.into_key());
1770 }
1771 }
1772 src.insert(key, value).unwrap();
1773 let entry = src.entry(key);
1774 match entry {
1775 Entry::Occupied(mut o) => {
1776 assert_eq!(&key, o.key());
1777 assert_eq!(&value, o.get());
1778 assert_eq!(&value, o.get_mut());
1779 assert_eq!(&value, o.into_mut());
1780 }
1781 Entry::Vacant(_) => {
1782 panic!("Entry not found");
1783 }
1784 }
1785 }
1786
1787 #[test]
1788 fn entry_vacant_insert() {
1789 let key = 0;
1790 let value = 0;
1791 let mut src = almost_filled_map();
1792 assert_eq!(MAP_SLOTS - 1, src.len());
1793 let entry = src.entry(key);
1794 match entry {
1795 Entry::Occupied(_) => {
1796 panic!("Entry found when empty");
1797 }
1798 Entry::Vacant(v) => {
1799 assert_eq!(value, *v.insert(value).unwrap());
1800 }
1801 };
1802 assert_eq!(value, *src.get(&key).unwrap());
1803 }
1804
1805 #[test]
1806 fn entry_occupied_insert() {
1807 let key = 0;
1808 let value = 0;
1809 let value2 = 5;
1810 let mut src = almost_filled_map();
1811 assert_eq!(MAP_SLOTS - 1, src.len());
1812 src.insert(key, value).unwrap();
1813 let entry = src.entry(key);
1814 match entry {
1815 Entry::Occupied(o) => {
1816 assert_eq!(value, o.insert(value2));
1817 }
1818 Entry::Vacant(_) => {
1819 panic!("Entry not found");
1820 }
1821 };
1822 assert_eq!(value2, *src.get(&key).unwrap());
1823 }
1824
1825 #[test]
1826 fn entry_remove_entry() {
1827 let key = 0;
1828 let value = 0;
1829 let mut src = almost_filled_map();
1830 src.insert(key, value).unwrap();
1831 assert_eq!(MAP_SLOTS, src.len());
1832 let entry = src.entry(key);
1833 match entry {
1834 Entry::Occupied(o) => {
1835 assert_eq!((key, value), o.remove_entry());
1836 }
1837 Entry::Vacant(_) => {
1838 panic!("Entry not found")
1839 }
1840 };
1841 assert_eq!(MAP_SLOTS - 1, src.len());
1842 }
1843
1844 #[test]
1845 fn entry_remove() {
1846 let key = 0;
1847 let value = 0;
1848 let mut src = almost_filled_map();
1849 src.insert(key, value).unwrap();
1850 assert_eq!(MAP_SLOTS, src.len());
1851 let entry = src.entry(key);
1852 match entry {
1853 Entry::Occupied(o) => {
1854 assert_eq!(value, o.remove());
1855 }
1856 Entry::Vacant(_) => {
1857 panic!("Entry not found");
1858 }
1859 };
1860 assert_eq!(MAP_SLOTS - 1, src.len());
1861 }
1862
1863 #[test]
1864 fn retain() {
1865 let mut none = almost_filled_map();
1866 none.retain(|_, _| false);
1867 assert!(none.is_empty());
1868
1869 let mut all = almost_filled_map();
1870 all.retain(|_, _| true);
1871 assert_eq!(all.len(), MAP_SLOTS - 1);
1872
1873 let mut even = almost_filled_map();
1874 even.retain(|_, &mut v| v.is_multiple_of(2));
1875 assert_eq!(even.len(), (MAP_SLOTS - 1) / 2);
1876 for &v in even.values() {
1877 assert_eq!(v % 2, 0);
1878 }
1879
1880 let mut odd = almost_filled_map();
1881 odd.retain(|_, &mut v| !v.is_multiple_of(2));
1882 assert_eq!(odd.len(), MAP_SLOTS / 2);
1883 for &v in odd.values() {
1884 assert_ne!(v % 2, 0);
1885 }
1886 assert_eq!(odd.insert(2, 2), Ok(None));
1887 assert_eq!(odd.len(), (MAP_SLOTS / 2) + 1);
1888 }
1889
1890 #[test]
1891 fn entry_roll_through_all() {
1892 let mut src: FnvIndexMap<usize, usize, MAP_SLOTS> = FnvIndexMap::new();
1893 for i in 0..MAP_SLOTS {
1894 match src.entry(i) {
1895 Entry::Occupied(_) => {
1896 panic!("Entry found before insert");
1897 }
1898 Entry::Vacant(v) => {
1899 assert_eq!(i, *v.insert(i).unwrap());
1900 }
1901 }
1902 }
1903 let add_mod = 99;
1904 for i in 0..MAP_SLOTS {
1905 match src.entry(i) {
1906 Entry::Occupied(o) => {
1907 assert_eq!(i, o.insert(i + add_mod));
1908 }
1909 Entry::Vacant(_) => {
1910 panic!("Entry not found after insert");
1911 }
1912 }
1913 }
1914 for i in 0..MAP_SLOTS {
1915 match src.entry(i) {
1916 Entry::Occupied(o) => {
1917 assert_eq!((i, i + add_mod), o.remove_entry());
1918 }
1919 Entry::Vacant(_) => {
1920 panic!("Entry not found after insert");
1921 }
1922 }
1923 }
1924 for i in 0..MAP_SLOTS {
1925 assert!(matches!(src.entry(i), Entry::Vacant(_)));
1926 }
1927 assert!(src.is_empty());
1928 }
1929
1930 #[test]
1931 fn first_last() {
1932 let mut map = FnvIndexMap::<_, _, 4>::new();
1933
1934 assert_eq!(None, map.first());
1935 assert_eq!(None, map.last());
1936
1937 map.insert(0, 0).unwrap();
1938 map.insert(2, 2).unwrap();
1939
1940 assert_eq!(Some((&0, &0)), map.first());
1941 assert_eq!(Some((&2, &2)), map.last());
1942
1943 map.insert(1, 1).unwrap();
1944
1945 assert_eq!(Some((&1, &1)), map.last());
1946
1947 *map.first_mut().unwrap().1 += 1;
1948 *map.last_mut().unwrap().1 += 1;
1949
1950 assert_eq!(Some((&0, &1)), map.first());
1951 assert_eq!(Some((&1, &2)), map.last());
1952 }
1953
1954 #[test]
1955 fn keys_iter() {
1956 let map = almost_filled_map();
1957 for (&key, i) in map.keys().zip(1..MAP_SLOTS) {
1958 assert_eq!(key, i);
1959 }
1960 }
1961
1962 #[test]
1963 fn values_iter() {
1964 let map = almost_filled_map();
1965 for (&value, i) in map.values().zip(1..MAP_SLOTS) {
1966 assert_eq!(value, i);
1967 }
1968 }
1969
1970 #[test]
1971 fn values_mut_iter() {
1972 let mut map = almost_filled_map();
1973 for value in map.values_mut() {
1974 *value += 1;
1975 }
1976
1977 for (&value, i) in map.values().zip(1..MAP_SLOTS) {
1978 assert_eq!(value, i + 1);
1979 }
1980 }
1981
1982 #[test]
1983 fn partial_eq_floats() {
1984 // Make sure `PartialEq` is implemented even if `V` doesn't implement `Eq`.
1985 let map: FnvIndexMap<usize, f32, 4> = Default::default();
1986 assert_eq!(map, map);
1987 }
1988}