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