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}