Skip to main content

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        struct Guard<'a, K, V, S, const N: usize>(&'a mut IndexMap<K, V, S, N>);
982        impl<'a, K, V, S, const N: usize> Drop for Guard<'a, K, V, S, N> {
983            fn drop(&mut self) {
984                for pos in self.0.core.indices.iter_mut() {
985                    *pos = None;
986                }
987            }
988        }
989        let this = Guard(self);
990        // SAFETY: Guard will be dropped and lead to a consistent empty state even in the case of a
991        // panic leading to unwinding during the dropping of an item
992        this.0.core.entries.clear();
993    }
994}
995
996impl<K, V, S, const N: usize> IndexMap<K, V, S, N>
997where
998    K: Eq + Hash,
999    S: BuildHasher,
1000{
1001    /* Public API */
1002    /// Returns an entry for the corresponding key
1003    /// ```
1004    /// use heapless::index_map::Entry;
1005    /// use heapless::index_map::FnvIndexMap;
1006    /// let mut map = FnvIndexMap::<_, _, 16>::new();
1007    /// if let Entry::Vacant(v) = map.entry("a") {
1008    ///     v.insert(1).unwrap();
1009    /// }
1010    /// if let Entry::Occupied(mut o) = map.entry("a") {
1011    ///     println!("found {}", *o.get()); // Prints 1
1012    ///     o.insert(2);
1013    /// }
1014    /// // Prints 2
1015    /// println!("val: {}", *map.get("a").unwrap());
1016    /// ```
1017    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, N> {
1018        let hash_val = hash_with(&key, &self.build_hasher);
1019        if let Some((probe, pos)) = self.core.find(hash_val, &key) {
1020            Entry::Occupied(OccupiedEntry {
1021                key,
1022                probe,
1023                pos,
1024                core: &mut self.core,
1025            })
1026        } else {
1027            Entry::Vacant(VacantEntry {
1028                key,
1029                hash_val,
1030                core: &mut self.core,
1031            })
1032        }
1033    }
1034
1035    /// Returns a reference to the value corresponding to the key.
1036    ///
1037    /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1038    /// form *must* match those for the key type.
1039    ///
1040    /// Computes in *O*(1) time (average).
1041    ///
1042    /// ```
1043    /// use heapless::index_map::FnvIndexMap;
1044    ///
1045    /// let mut map = FnvIndexMap::<_, _, 16>::new();
1046    /// map.insert(1, "a").unwrap();
1047    /// assert_eq!(map.get(&1), Some(&"a"));
1048    /// assert_eq!(map.get(&2), None);
1049    /// ```
1050    pub fn get<Q>(&self, key: &Q) -> Option<&V>
1051    where
1052        K: Borrow<Q>,
1053        Q: ?Sized + Hash + Eq,
1054    {
1055        self.find(key)
1056            .map(|(_, found)| unsafe { &self.core.entries.get_unchecked(found).value })
1057    }
1058
1059    /// Returns true if the map contains a value for the specified key.
1060    ///
1061    /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1062    /// form *must* match those for the key type.
1063    ///
1064    /// Computes in *O*(1) time (average).
1065    ///
1066    /// # Examples
1067    ///
1068    /// ```
1069    /// use heapless::index_map::FnvIndexMap;
1070    ///
1071    /// let mut map = FnvIndexMap::<_, _, 8>::new();
1072    /// map.insert(1, "a").unwrap();
1073    /// assert_eq!(map.contains_key(&1), true);
1074    /// assert_eq!(map.contains_key(&2), false);
1075    /// ```
1076    pub fn contains_key<Q>(&self, key: &Q) -> bool
1077    where
1078        K: Borrow<Q>,
1079        Q: ?Sized + Eq + Hash,
1080    {
1081        self.find(key).is_some()
1082    }
1083
1084    /// Returns a mutable reference to the value corresponding to the key.
1085    ///
1086    /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1087    /// form *must* match those for the key type.
1088    ///
1089    /// Computes in *O*(1) time (average).
1090    ///
1091    /// # Examples
1092    ///
1093    /// ```
1094    /// use heapless::index_map::FnvIndexMap;
1095    ///
1096    /// let mut map = FnvIndexMap::<_, _, 8>::new();
1097    /// map.insert(1, "a").unwrap();
1098    /// if let Some(x) = map.get_mut(&1) {
1099    ///     *x = "b";
1100    /// }
1101    /// assert_eq!(map[&1], "b");
1102    /// ```
1103    pub fn get_mut<'v, Q>(&'v mut self, key: &Q) -> Option<&'v mut V>
1104    where
1105        K: Borrow<Q>,
1106        Q: ?Sized + Hash + Eq,
1107    {
1108        if let Some((_, found)) = self.find(key) {
1109            Some(unsafe { &mut self.core.entries.get_unchecked_mut(found).value })
1110        } else {
1111            None
1112        }
1113    }
1114
1115    /// Returns a tuple of references to the key and the value corresponding to the index.
1116    ///
1117    /// Computes in *O*(1) time (average).
1118    ///
1119    /// # Examples
1120    ///
1121    /// ```
1122    /// use heapless::index_map::FnvIndexMap;
1123    ///
1124    /// let mut map = FnvIndexMap::<_, _, 16>::new();
1125    /// map.insert(1, "a").unwrap();
1126    /// assert_eq!(map.get_index(0), Some((&1, &"a")));
1127    /// assert_eq!(map.get_index(1), None);
1128    /// ```
1129    pub fn get_index(&self, index: usize) -> Option<(&K, &V)> {
1130        self.core
1131            .entries
1132            .get(index)
1133            .map(|entry| (&entry.key, &entry.value))
1134    }
1135
1136    /// Returns a tuple of references to the key and the mutable value corresponding to the index.
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    /// if let Some((_, x)) = map.get_index_mut(0) {
1148    ///     *x = "b";
1149    /// }
1150    /// assert_eq!(map[&1], "b");
1151    /// ```
1152    pub fn get_index_mut(&mut self, index: usize) -> Option<(&K, &mut V)> {
1153        self.core
1154            .entries
1155            .get_mut(index)
1156            .map(|entry| (&entry.key, &mut entry.value))
1157    }
1158
1159    /// Returns the index of the key-value pair corresponding to the key.
1160    ///
1161    /// The key may be any borrowed form of the map's key type, but `Hash` and `Eq` on the borrowed
1162    /// form *must* match those for the key type.
1163    ///
1164    /// Computes in *O*(1) time (average).
1165    ///
1166    /// # Examples
1167    ///
1168    /// ```
1169    /// use heapless::index_map::FnvIndexMap;
1170    ///
1171    /// let mut map = FnvIndexMap::<_, _, 8>::new();
1172    /// map.insert(1, "a").unwrap();
1173    /// map.insert(0, "b").unwrap();
1174    /// assert_eq!(map.get_index_of(&0), Some(1));
1175    /// assert_eq!(map.get_index_of(&1), Some(0));
1176    /// assert_eq!(map.get_index_of(&2), None);
1177    /// ```
1178    pub fn get_index_of<Q>(&self, key: &Q) -> Option<usize>
1179    where
1180        K: Borrow<Q>,
1181        Q: ?Sized + Hash + Eq,
1182    {
1183        self.find(key).map(|(_, found)| found)
1184    }
1185
1186    /// Inserts a key-value pair into the map.
1187    ///
1188    /// If an equivalent key already exists in the map: the key remains and retains in its place in
1189    /// the order, its corresponding value is updated with `value` and the older value is returned
1190    /// inside `Some(_)`.
1191    ///
1192    /// If no equivalent key existed in the map: the new key-value pair is inserted, last in order,
1193    /// and `None` is returned.
1194    ///
1195    /// Computes in *O*(1) time (average).
1196    ///
1197    /// See also entry if you you want to insert or modify or if you need to get the index of the
1198    /// corresponding key-value pair.
1199    ///
1200    /// # Examples
1201    ///
1202    /// ```
1203    /// use heapless::index_map::FnvIndexMap;
1204    ///
1205    /// let mut map = FnvIndexMap::<_, _, 8>::new();
1206    /// assert_eq!(map.insert(37, "a"), Ok(None));
1207    /// assert_eq!(map.is_empty(), false);
1208    ///
1209    /// map.insert(37, "b");
1210    /// assert_eq!(map.insert(37, "c"), Ok(Some("b")));
1211    /// assert_eq!(map[&37], "c");
1212    /// ```
1213    pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V)> {
1214        let hash = hash_with(&key, &self.build_hasher);
1215        match self.core.insert(hash, key, value) {
1216            Insert::Success(inserted) => Ok(inserted.old_value),
1217            Insert::Full((k, v)) => Err((k, v)),
1218        }
1219    }
1220
1221    /// Same as [`swap_remove`](Self::swap_remove)
1222    ///
1223    /// Computes in *O*(1) time (average).
1224    ///
1225    /// # Examples
1226    ///
1227    /// ```
1228    /// use heapless::index_map::FnvIndexMap;
1229    ///
1230    /// let mut map = FnvIndexMap::<_, _, 8>::new();
1231    /// map.insert(1, "a").unwrap();
1232    /// assert_eq!(map.remove(&1), Some("a"));
1233    /// assert_eq!(map.remove(&1), None);
1234    /// ```
1235    pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
1236    where
1237        K: Borrow<Q>,
1238        Q: ?Sized + Hash + Eq,
1239    {
1240        self.swap_remove(key)
1241    }
1242
1243    /// Remove the key-value pair equivalent to `key` and return its value.
1244    ///
1245    /// Like `Vec::swap_remove`, the pair is removed by swapping it with the last element of the map
1246    /// and popping it off. **This perturbs the position of what used to be the last element!**
1247    ///
1248    /// Return `None` if `key` is not in map.
1249    ///
1250    /// Computes in *O*(1) time (average).
1251    pub fn swap_remove<Q>(&mut self, key: &Q) -> Option<V>
1252    where
1253        K: Borrow<Q>,
1254        Q: ?Sized + Hash + Eq,
1255    {
1256        self.find(key)
1257            .map(|(probe, found)| self.core.remove_found(probe, found).1)
1258    }
1259
1260    /// Retains only the elements specified by the predicate.
1261    ///
1262    /// In other words, remove all pairs `(k, v)` for which `f(&k, &mut v)` returns `false`.
1263    pub fn retain<F>(&mut self, mut f: F)
1264    where
1265        F: FnMut(&K, &mut V) -> bool,
1266    {
1267        self.core.retain_in_order(move |k, v| f(k, v));
1268    }
1269
1270    /// Shortens the map, keeping the first `len` elements and dropping the rest.
1271    ///
1272    /// If `len` is greater than the map's current length, this has no effect.
1273    ///
1274    /// Computes in *O*(n) time (average).
1275    ///
1276    /// # Examples
1277    ///
1278    /// ```
1279    /// use heapless::index_map::FnvIndexMap;
1280    ///
1281    /// let mut map = FnvIndexMap::<_, _, 8>::new();
1282    /// map.insert(3, "a").unwrap();
1283    /// map.insert(2, "b").unwrap();
1284    /// map.insert(1, "c").unwrap();
1285    /// map.truncate(2);
1286    /// assert_eq!(map.len(), 2);
1287    /// assert_eq!(map.get(&1), None);
1288    ///
1289    /// let mut iter = map.iter();
1290    /// assert_eq!(iter.next(), Some((&3, &"a")));
1291    /// assert_eq!(iter.next(), Some((&2, &"b")));
1292    /// assert_eq!(iter.next(), None);
1293    /// ```
1294    pub fn truncate(&mut self, len: usize) {
1295        self.core.entries.truncate(len);
1296
1297        if self.core.indices.len() > self.core.entries.len() {
1298            for index in self.core.indices.iter_mut() {
1299                match index {
1300                    Some(pos) if pos.index() >= len => *index = None,
1301                    _ => (),
1302                }
1303            }
1304        }
1305    }
1306
1307    /* Private API */
1308    /// Return probe (indices) and position (entries)
1309    fn find<Q>(&self, key: &Q) -> Option<(usize, usize)>
1310    where
1311        K: Borrow<Q>,
1312        Q: ?Sized + Hash + Eq,
1313    {
1314        if self.is_empty() {
1315            return None;
1316        }
1317        let h = hash_with(key, &self.build_hasher);
1318        self.core.find(h, key)
1319    }
1320}
1321
1322impl<K, Q, V, S, const N: usize> ops::Index<&Q> for IndexMap<K, V, S, N>
1323where
1324    K: Eq + Hash + Borrow<Q>,
1325    Q: ?Sized + Eq + Hash,
1326    S: BuildHasher,
1327{
1328    type Output = V;
1329
1330    fn index(&self, key: &Q) -> &V {
1331        self.get(key).expect("key not found")
1332    }
1333}
1334
1335impl<K, Q, V, S, const N: usize> ops::IndexMut<&Q> for IndexMap<K, V, S, N>
1336where
1337    K: Eq + Hash + Borrow<Q>,
1338    Q: ?Sized + Eq + Hash,
1339    S: BuildHasher,
1340{
1341    fn index_mut(&mut self, key: &Q) -> &mut V {
1342        self.get_mut(key).expect("key not found")
1343    }
1344}
1345
1346impl<K, V, S, const N: usize> Clone for IndexMap<K, V, S, N>
1347where
1348    K: Clone,
1349    V: Clone,
1350    S: Clone,
1351{
1352    fn clone(&self) -> Self {
1353        Self {
1354            core: self.core.clone(),
1355            build_hasher: self.build_hasher.clone(),
1356        }
1357    }
1358}
1359
1360impl<K, V, S, const N: usize> fmt::Debug for IndexMap<K, V, S, N>
1361where
1362    K: fmt::Debug,
1363    V: fmt::Debug,
1364{
1365    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1366        f.debug_map().entries(self.iter()).finish()
1367    }
1368}
1369
1370impl<K, V, S, const N: usize> Default for IndexMap<K, V, S, N>
1371where
1372    S: Default,
1373{
1374    fn default() -> Self {
1375        const {
1376            assert!(N > 1);
1377            assert!(N.is_power_of_two());
1378        }
1379
1380        Self {
1381            build_hasher: <_>::default(),
1382            core: CoreMap::new(),
1383        }
1384    }
1385}
1386
1387impl<K, V1, V2, S1, S2, const N1: usize, const N2: usize> PartialEq<IndexMap<K, V2, S2, N2>>
1388    for IndexMap<K, V1, S1, N1>
1389where
1390    K: Eq + Hash,
1391    V1: PartialEq<V2>,
1392    S1: BuildHasher,
1393    S2: BuildHasher,
1394{
1395    fn eq(&self, other: &IndexMap<K, V2, S2, N2>) -> bool {
1396        self.len() == other.len()
1397            && self
1398                .iter()
1399                .all(|(key, value)| other.get(key).is_some_and(|v| *value == *v))
1400    }
1401}
1402
1403impl<K, V, S, const N: usize> Eq for IndexMap<K, V, S, N>
1404where
1405    K: Eq + Hash,
1406    V: Eq,
1407    S: BuildHasher,
1408{
1409}
1410
1411impl<K, V, S, const N: usize> Extend<(K, V)> for IndexMap<K, V, S, N>
1412where
1413    K: Eq + Hash,
1414    S: BuildHasher,
1415{
1416    fn extend<I>(&mut self, iterable: I)
1417    where
1418        I: IntoIterator<Item = (K, V)>,
1419    {
1420        for (k, v) in iterable {
1421            self.insert(k, v).ok().unwrap();
1422        }
1423    }
1424}
1425
1426impl<'a, K, V, S, const N: usize> Extend<(&'a K, &'a V)> for IndexMap<K, V, S, N>
1427where
1428    K: Eq + Hash + Copy,
1429    V: Copy,
1430    S: BuildHasher,
1431{
1432    fn extend<I>(&mut self, iterable: I)
1433    where
1434        I: IntoIterator<Item = (&'a K, &'a V)>,
1435    {
1436        self.extend(iterable.into_iter().map(|(&key, &value)| (key, value)));
1437    }
1438}
1439
1440impl<K, V, S, const N: usize> FromIterator<(K, V)> for IndexMap<K, V, S, N>
1441where
1442    K: Eq + Hash,
1443    S: BuildHasher + Default,
1444{
1445    fn from_iter<I>(iterable: I) -> Self
1446    where
1447        I: IntoIterator<Item = (K, V)>,
1448    {
1449        let mut map = Self::default();
1450        map.extend(iterable);
1451        map
1452    }
1453}
1454
1455/// An owning iterator over the entries of an `IndexMap`.
1456///
1457/// This `struct` is created by the [`into_iter`] method on [`IndexMap`]
1458/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1459///
1460/// [`into_iter`]: IntoIterator::into_iter
1461///
1462/// # Example
1463///
1464/// ```
1465/// use heapless::index_map::FnvIndexMap;
1466///
1467/// let mut map = FnvIndexMap::<_, _, 16>::new();
1468/// map.insert("a", 1).unwrap();
1469///
1470/// let iter = map.into_iter();
1471/// ```
1472#[derive(Clone)]
1473pub struct IntoIter<K, V, const N: usize> {
1474    entries: Vec<Bucket<K, V>, N, usize>,
1475}
1476
1477impl<K, V, const N: usize> Iterator for IntoIter<K, V, N> {
1478    type Item = (K, V);
1479
1480    fn next(&mut self) -> Option<Self::Item> {
1481        self.entries.pop().map(|bucket| (bucket.key, bucket.value))
1482    }
1483
1484    fn size_hint(&self) -> (usize, Option<usize>) {
1485        let len = self.len();
1486        (len, Some(len))
1487    }
1488}
1489
1490impl<K, V, const N: usize> FusedIterator for IntoIter<K, V, N> {}
1491
1492impl<K, V, const N: usize> ExactSizeIterator for IntoIter<K, V, N> {
1493    fn len(&self) -> usize {
1494        self.entries.len()
1495    }
1496}
1497
1498impl<K, V, S, const N: usize> IntoIterator for IndexMap<K, V, S, N> {
1499    type Item = (K, V);
1500    type IntoIter = IntoIter<K, V, N>;
1501
1502    fn into_iter(self) -> Self::IntoIter {
1503        IntoIter {
1504            entries: self.core.entries,
1505        }
1506    }
1507}
1508
1509impl<'a, K, V, S, const N: usize> IntoIterator for &'a IndexMap<K, V, S, N> {
1510    type Item = (&'a K, &'a V);
1511    type IntoIter = Iter<'a, K, V>;
1512
1513    fn into_iter(self) -> Self::IntoIter {
1514        self.iter()
1515    }
1516}
1517
1518impl<'a, K, V, S, const N: usize> IntoIterator for &'a mut IndexMap<K, V, S, N> {
1519    type Item = (&'a K, &'a mut V);
1520    type IntoIter = IterMut<'a, K, V>;
1521
1522    fn into_iter(self) -> Self::IntoIter {
1523        self.iter_mut()
1524    }
1525}
1526
1527/// An iterator over the items of a [`IndexMap`].
1528///
1529/// This `struct` is created by the [`iter`](IndexMap::iter) method on [`IndexMap`]. See its
1530/// documentation for more.
1531pub struct Iter<'a, K, V> {
1532    iter: slice::Iter<'a, Bucket<K, V>>,
1533}
1534
1535impl<'a, K, V> Iterator for Iter<'a, K, V> {
1536    type Item = (&'a K, &'a V);
1537
1538    fn next(&mut self) -> Option<Self::Item> {
1539        self.iter.next().map(|bucket| (&bucket.key, &bucket.value))
1540    }
1541}
1542
1543impl<K, V> Clone for Iter<'_, K, V> {
1544    fn clone(&self) -> Self {
1545        Self {
1546            iter: self.iter.clone(),
1547        }
1548    }
1549}
1550
1551/// A mutable iterator over the items of a [`IndexMap`].
1552///
1553/// This `struct` is created by the [`iter_mut`](IndexMap::iter_mut) method on [`IndexMap`]. See its
1554/// documentation for more.
1555pub struct IterMut<'a, K, V> {
1556    iter: slice::IterMut<'a, Bucket<K, V>>,
1557}
1558
1559impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1560    type Item = (&'a K, &'a mut V);
1561
1562    fn next(&mut self) -> Option<Self::Item> {
1563        self.iter
1564            .next()
1565            .map(|bucket| (&bucket.key, &mut bucket.value))
1566    }
1567}
1568
1569/// An iterator over the keys of a [`IndexMap`].
1570///
1571/// This `struct` is created by the [`keys`](IndexMap::keys) method on [`IndexMap`]. See its
1572/// documentation for more.
1573pub struct Keys<'a, K, V> {
1574    iter: slice::Iter<'a, Bucket<K, V>>,
1575}
1576
1577impl<'a, K, V> Iterator for Keys<'a, K, V> {
1578    type Item = &'a K;
1579
1580    fn next(&mut self) -> Option<Self::Item> {
1581        self.iter.next().map(|bucket| &bucket.key)
1582    }
1583}
1584
1585/// An iterator over the values of a [`IndexMap`].
1586///
1587/// This `struct` is created by the [`values`](IndexMap::values) method on [`IndexMap`]. See its
1588/// documentation for more.
1589pub struct Values<'a, K, V> {
1590    iter: slice::Iter<'a, Bucket<K, V>>,
1591}
1592
1593impl<'a, K, V> Iterator for Values<'a, K, V> {
1594    type Item = &'a V;
1595
1596    fn next(&mut self) -> Option<Self::Item> {
1597        self.iter.next().map(|bucket| &bucket.value)
1598    }
1599}
1600
1601/// A mutable iterator over the values of a [`IndexMap`].
1602///
1603/// This `struct` is created by the [`values_mut`](IndexMap::values_mut) method on [`IndexMap`]. See
1604/// its documentation for more.
1605pub struct ValuesMut<'a, K, V> {
1606    iter: slice::IterMut<'a, Bucket<K, V>>,
1607}
1608
1609impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
1610    type Item = &'a mut V;
1611
1612    fn next(&mut self) -> Option<Self::Item> {
1613        self.iter.next().map(|bucket| &mut bucket.value)
1614    }
1615}
1616
1617fn hash_with<K, S>(key: &K, build_hasher: &S) -> HashValue
1618where
1619    K: ?Sized + Hash,
1620    S: BuildHasher,
1621{
1622    HashValue(build_hasher.hash_one(key) as u16)
1623}
1624
1625#[cfg(test)]
1626mod tests {
1627    use core::mem;
1628    use std::{
1629        mem::ManuallyDrop,
1630        panic::{catch_unwind, AssertUnwindSafe},
1631        sync::atomic::{AtomicI32, Ordering},
1632    };
1633
1634    use static_assertions::assert_not_impl_any;
1635
1636    use super::{BuildHasherDefault, Entry, FnvIndexMap, IndexMap};
1637
1638    // Ensure a `IndexMap` containing `!Send` keys stays `!Send` itself.
1639    assert_not_impl_any!(IndexMap<*const (), (), BuildHasherDefault<()>, 4>: Send);
1640    // Ensure a `IndexMap` containing `!Send` values stays `!Send` itself.
1641    assert_not_impl_any!(IndexMap<(), *const (), BuildHasherDefault<()>, 4>: Send);
1642
1643    #[test]
1644    fn size() {
1645        const CAP: usize = 4;
1646        assert_eq!(
1647            mem::size_of::<FnvIndexMap<i16, u16, CAP>>(),
1648            CAP * mem::size_of::<u32>() + // indices
1649                CAP * (mem::size_of::<i16>() + // key
1650                     mem::size_of::<u16>() + // value
1651                     mem::size_of::<u16>() // hash
1652                ) + // buckets
1653                mem::size_of::<usize>() // entries.length
1654        );
1655    }
1656
1657    #[test]
1658    fn partial_eq() {
1659        {
1660            let mut a: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1661            a.insert("k1", "v1").unwrap();
1662
1663            let mut b: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1664            b.insert("k1", "v1").unwrap();
1665
1666            assert!(a == b);
1667
1668            b.insert("k2", "v2").unwrap();
1669
1670            assert!(a != b);
1671        }
1672
1673        {
1674            let mut a: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1675            a.insert("k1", "v1").unwrap();
1676            a.insert("k2", "v2").unwrap();
1677
1678            let mut b: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1679            b.insert("k2", "v2").unwrap();
1680            b.insert("k1", "v1").unwrap();
1681
1682            assert!(a == b);
1683        }
1684    }
1685
1686    #[test]
1687    fn entry_or_insert() {
1688        let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1689        a.entry("k1").or_insert("v1").unwrap();
1690        assert_eq!(a["k1"], "v1");
1691
1692        a.entry("k2").or_insert("v2").unwrap();
1693        assert_eq!(a["k2"], "v2");
1694
1695        let result = a.entry("k3").or_insert("v3");
1696        assert_eq!(result, Err("v3"));
1697    }
1698
1699    #[test]
1700    fn entry_or_insert_with() {
1701        let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1702        a.entry("k1").or_insert_with(|| "v1").unwrap();
1703        assert_eq!(a["k1"], "v1");
1704
1705        a.entry("k2").or_insert_with(|| "v2").unwrap();
1706        assert_eq!(a["k2"], "v2");
1707
1708        let result = a.entry("k3").or_insert_with(|| "v3");
1709        assert_eq!(result, Err("v3"));
1710    }
1711
1712    #[test]
1713    fn entry_or_insert_with_key() {
1714        let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1715        a.entry("k1")
1716            .or_insert_with_key(|key| key.chars().count())
1717            .unwrap();
1718        assert_eq!(a["k1"], 2);
1719
1720        a.entry("k22")
1721            .or_insert_with_key(|key| key.chars().count())
1722            .unwrap();
1723        assert_eq!(a["k22"], 3);
1724
1725        let result = a.entry("k3").or_insert_with_key(|key| key.chars().count());
1726        assert_eq!(result, Err(2));
1727    }
1728
1729    #[test]
1730    fn entry_key() {
1731        let mut a: FnvIndexMap<&str, &str, 2> = FnvIndexMap::new();
1732
1733        assert_eq!(a.entry("k1").key(), &"k1");
1734    }
1735
1736    #[test]
1737    fn entry_and_modify() {
1738        let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1739        a.insert("k1", "v1").unwrap();
1740        a.entry("k1").and_modify(|e| *e = "modified v1");
1741
1742        assert_eq!(a["k1"], "modified v1");
1743
1744        a.entry("k2")
1745            .and_modify(|e| *e = "v2")
1746            .or_insert("default v2")
1747            .unwrap();
1748
1749        assert_eq!(a["k2"], "default v2");
1750    }
1751
1752    #[test]
1753    fn entry_or_default() {
1754        let mut a: FnvIndexMap<&str, Option<u32>, 2> = FnvIndexMap::new();
1755        a.entry("k1").or_default().unwrap();
1756
1757        assert_eq!(a["k1"], None);
1758
1759        let mut b: FnvIndexMap<&str, u8, 2> = FnvIndexMap::new();
1760        b.entry("k2").or_default().unwrap();
1761
1762        assert_eq!(b["k2"], 0);
1763    }
1764
1765    #[test]
1766    fn into_iter() {
1767        let mut src: FnvIndexMap<_, _, 4> = FnvIndexMap::new();
1768        src.insert("k1", "v1").unwrap();
1769        src.insert("k2", "v2").unwrap();
1770        src.insert("k3", "v3").unwrap();
1771        src.insert("k4", "v4").unwrap();
1772        let clone = src.clone();
1773        for (k, v) in clone.into_iter() {
1774            assert_eq!(v, src.remove(k).unwrap());
1775        }
1776        assert!(src.is_empty());
1777    }
1778
1779    #[test]
1780    fn into_iter_len() {
1781        let mut src: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1782        src.insert("k1", "v1").unwrap();
1783        src.insert("k2", "v2").unwrap();
1784
1785        let mut items = src.into_iter();
1786        assert_eq!(items.len(), 2);
1787        let _ = items.next();
1788        assert_eq!(items.len(), 1);
1789        let _ = items.next();
1790        assert_eq!(items.len(), 0);
1791    }
1792
1793    #[test]
1794    fn insert_replaces_on_full_map() {
1795        let mut a: FnvIndexMap<_, _, 2> = FnvIndexMap::new();
1796        a.insert("k1", "v1").unwrap();
1797        a.insert("k2", "v2").unwrap();
1798        a.insert("k1", "v2").unwrap();
1799        assert_eq!(a.get("k1"), a.get("k2"));
1800    }
1801
1802    // tests that use this constant take too long to run under miri, specially on CI, with a map of
1803    // this size so make the map smaller when using miri
1804    #[cfg(not(any(miri, target_os = "vxworks")))]
1805    const MAP_SLOTS: usize = 4096;
1806    // Reduce number of slots as too many slots can cause a stack overflow on VxWorks.
1807    #[cfg(target_os = "vxworks")]
1808    const MAP_SLOTS: usize = 1024;
1809    #[cfg(miri)]
1810    const MAP_SLOTS: usize = 64;
1811    fn almost_filled_map() -> FnvIndexMap<usize, usize, MAP_SLOTS> {
1812        let mut almost_filled = FnvIndexMap::new();
1813        for i in 1..MAP_SLOTS {
1814            almost_filled.insert(i, i).unwrap();
1815        }
1816        almost_filled
1817    }
1818
1819    #[test]
1820    fn entry_find() {
1821        let key = 0;
1822        let value = 0;
1823        let mut src = almost_filled_map();
1824        let entry = src.entry(key);
1825        match entry {
1826            Entry::Occupied(_) => {
1827                panic!("Found entry without inserting");
1828            }
1829            Entry::Vacant(v) => {
1830                assert_eq!(&key, v.key());
1831                assert_eq!(key, v.into_key());
1832            }
1833        }
1834        src.insert(key, value).unwrap();
1835        let entry = src.entry(key);
1836        match entry {
1837            Entry::Occupied(mut o) => {
1838                assert_eq!(&key, o.key());
1839                assert_eq!(&value, o.get());
1840                assert_eq!(&value, o.get_mut());
1841                assert_eq!(&value, o.into_mut());
1842            }
1843            Entry::Vacant(_) => {
1844                panic!("Entry not found");
1845            }
1846        }
1847    }
1848
1849    #[test]
1850    fn entry_vacant_insert() {
1851        let key = 0;
1852        let value = 0;
1853        let mut src = almost_filled_map();
1854        assert_eq!(MAP_SLOTS - 1, src.len());
1855        let entry = src.entry(key);
1856        match entry {
1857            Entry::Occupied(_) => {
1858                panic!("Entry found when empty");
1859            }
1860            Entry::Vacant(v) => {
1861                assert_eq!(value, *v.insert(value).unwrap());
1862            }
1863        };
1864        assert_eq!(value, *src.get(&key).unwrap());
1865    }
1866
1867    #[test]
1868    fn entry_occupied_insert() {
1869        let key = 0;
1870        let value = 0;
1871        let value2 = 5;
1872        let mut src = almost_filled_map();
1873        assert_eq!(MAP_SLOTS - 1, src.len());
1874        src.insert(key, value).unwrap();
1875        let entry = src.entry(key);
1876        match entry {
1877            Entry::Occupied(o) => {
1878                assert_eq!(value, o.insert(value2));
1879            }
1880            Entry::Vacant(_) => {
1881                panic!("Entry not found");
1882            }
1883        };
1884        assert_eq!(value2, *src.get(&key).unwrap());
1885    }
1886
1887    #[test]
1888    fn entry_remove_entry() {
1889        let key = 0;
1890        let value = 0;
1891        let mut src = almost_filled_map();
1892        src.insert(key, value).unwrap();
1893        assert_eq!(MAP_SLOTS, src.len());
1894        let entry = src.entry(key);
1895        match entry {
1896            Entry::Occupied(o) => {
1897                assert_eq!((key, value), o.remove_entry());
1898            }
1899            Entry::Vacant(_) => {
1900                panic!("Entry not found")
1901            }
1902        };
1903        assert_eq!(MAP_SLOTS - 1, src.len());
1904    }
1905
1906    #[test]
1907    fn entry_remove() {
1908        let key = 0;
1909        let value = 0;
1910        let mut src = almost_filled_map();
1911        src.insert(key, value).unwrap();
1912        assert_eq!(MAP_SLOTS, src.len());
1913        let entry = src.entry(key);
1914        match entry {
1915            Entry::Occupied(o) => {
1916                assert_eq!(value, o.remove());
1917            }
1918            Entry::Vacant(_) => {
1919                panic!("Entry not found");
1920            }
1921        };
1922        assert_eq!(MAP_SLOTS - 1, src.len());
1923    }
1924
1925    #[test]
1926    fn retain() {
1927        let mut none = almost_filled_map();
1928        none.retain(|_, _| false);
1929        assert!(none.is_empty());
1930
1931        let mut all = almost_filled_map();
1932        all.retain(|_, _| true);
1933        assert_eq!(all.len(), MAP_SLOTS - 1);
1934
1935        let mut even = almost_filled_map();
1936        even.retain(|_, &mut v| v.is_multiple_of(2));
1937        assert_eq!(even.len(), (MAP_SLOTS - 1) / 2);
1938        for &v in even.values() {
1939            assert_eq!(v % 2, 0);
1940        }
1941
1942        let mut odd = almost_filled_map();
1943        odd.retain(|_, &mut v| !v.is_multiple_of(2));
1944        assert_eq!(odd.len(), MAP_SLOTS / 2);
1945        for &v in odd.values() {
1946            assert_ne!(v % 2, 0);
1947        }
1948        assert_eq!(odd.insert(2, 2), Ok(None));
1949        assert_eq!(odd.len(), (MAP_SLOTS / 2) + 1);
1950    }
1951
1952    #[test]
1953    fn entry_roll_through_all() {
1954        let mut src: FnvIndexMap<usize, usize, MAP_SLOTS> = FnvIndexMap::new();
1955        for i in 0..MAP_SLOTS {
1956            match src.entry(i) {
1957                Entry::Occupied(_) => {
1958                    panic!("Entry found before insert");
1959                }
1960                Entry::Vacant(v) => {
1961                    assert_eq!(i, *v.insert(i).unwrap());
1962                }
1963            }
1964        }
1965        let add_mod = 99;
1966        for i in 0..MAP_SLOTS {
1967            match src.entry(i) {
1968                Entry::Occupied(o) => {
1969                    assert_eq!(i, o.insert(i + add_mod));
1970                }
1971                Entry::Vacant(_) => {
1972                    panic!("Entry not found after insert");
1973                }
1974            }
1975        }
1976        for i in 0..MAP_SLOTS {
1977            match src.entry(i) {
1978                Entry::Occupied(o) => {
1979                    assert_eq!((i, i + add_mod), o.remove_entry());
1980                }
1981                Entry::Vacant(_) => {
1982                    panic!("Entry not found after insert");
1983                }
1984            }
1985        }
1986        for i in 0..MAP_SLOTS {
1987            assert!(matches!(src.entry(i), Entry::Vacant(_)));
1988        }
1989        assert!(src.is_empty());
1990    }
1991
1992    #[test]
1993    fn first_last() {
1994        let mut map = FnvIndexMap::<_, _, 4>::new();
1995
1996        assert_eq!(None, map.first());
1997        assert_eq!(None, map.last());
1998
1999        map.insert(0, 0).unwrap();
2000        map.insert(2, 2).unwrap();
2001
2002        assert_eq!(Some((&0, &0)), map.first());
2003        assert_eq!(Some((&2, &2)), map.last());
2004
2005        map.insert(1, 1).unwrap();
2006
2007        assert_eq!(Some((&1, &1)), map.last());
2008
2009        *map.first_mut().unwrap().1 += 1;
2010        *map.last_mut().unwrap().1 += 1;
2011
2012        assert_eq!(Some((&0, &1)), map.first());
2013        assert_eq!(Some((&1, &2)), map.last());
2014    }
2015
2016    #[test]
2017    fn keys_iter() {
2018        let map = almost_filled_map();
2019        for (&key, i) in map.keys().zip(1..MAP_SLOTS) {
2020            assert_eq!(key, i);
2021        }
2022    }
2023
2024    #[test]
2025    fn values_iter() {
2026        let map = almost_filled_map();
2027        for (&value, i) in map.values().zip(1..MAP_SLOTS) {
2028            assert_eq!(value, i);
2029        }
2030    }
2031
2032    #[test]
2033    fn values_mut_iter() {
2034        let mut map = almost_filled_map();
2035        for value in map.values_mut() {
2036            *value += 1;
2037        }
2038
2039        for (&value, i) in map.values().zip(1..MAP_SLOTS) {
2040            assert_eq!(value, i + 1);
2041        }
2042    }
2043
2044    #[test]
2045    fn partial_eq_floats() {
2046        // Make sure `PartialEq` is implemented even if `V` doesn't implement `Eq`.
2047        let map: FnvIndexMap<usize, f32, 4> = Default::default();
2048        assert_eq!(map, map);
2049    }
2050
2051    #[test]
2052    #[cfg(feature = "zeroize")]
2053    fn test_index_map_zeroize() {
2054        use zeroize::Zeroize;
2055
2056        let mut map: FnvIndexMap<u8, u8, 8> = FnvIndexMap::new();
2057        for i in 1..=8 {
2058            map.insert(i, i * 10).unwrap();
2059        }
2060
2061        assert_eq!(map.len(), 8);
2062        assert!(!map.is_empty());
2063
2064        // zeroized using Vec's implementation
2065        map.zeroize();
2066
2067        assert_eq!(map.len(), 0);
2068        assert!(map.is_empty());
2069
2070        map.insert(1, 10).unwrap();
2071        assert_eq!(map.len(), 1);
2072        assert_eq!(map.get(&1), Some(&10));
2073    }
2074
2075    #[test]
2076    fn test_use_after_free_clear() {
2077        // See https://github.com/rust-embedded/heapless/issues/646
2078
2079        static COUNT: AtomicI32 = AtomicI32::new(0);
2080
2081        #[derive(Debug, Hash, PartialEq, Eq)]
2082        #[allow(unused)]
2083        struct Dropper();
2084
2085        impl Dropper {
2086            fn new() -> Self {
2087                COUNT.fetch_add(1, Ordering::Relaxed);
2088                Self()
2089            }
2090            fn count() -> i32 {
2091                COUNT.load(Ordering::Relaxed)
2092            }
2093        }
2094        impl Drop for Dropper {
2095            fn drop(&mut self) {
2096                COUNT.fetch_sub(1, Ordering::Relaxed);
2097                panic!("Testing  panicking");
2098            }
2099        }
2100
2101        let mut history_buf = FnvIndexMap::<Dropper, u32, 8>::new();
2102        history_buf.insert(Dropper::new(), 0).unwrap();
2103        // Don't panic on dropping of the history_buf
2104        let mut history_buf = ManuallyDrop::new(history_buf);
2105        let mut unwind_safe_history_buf = AssertUnwindSafe(&mut history_buf);
2106
2107        catch_unwind(move || unwind_safe_history_buf.clear()).unwrap_err();
2108        assert_eq!(history_buf.len(), 0);
2109        history_buf.clear();
2110        assert_eq!(Dropper::count(), 0);
2111    }
2112}