compact_map/
lib.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7//! Small map in various sizes. These store a certain number of entries inline, and fall back
8//! to a `HashMap` for larger allocations.
9//!
10//! Provides (almost) 1:1 API compatibility with [`HashMap`].
11//!
12//! # Examples
13//!
14//! ```
15//! use compact_map::CompactMap;
16//!
17//! // Type inference lets us omit an explicit type signature except for the capacity
18//! // (which would be `CompactMap<String, String, N>` in this example).
19//! // Also with default capacity of 16.
20//! let mut book_reviews = CompactMap::default();
21//!
22//! // Review some books.
23//! book_reviews.insert(
24//!     "Adventures of Huckleberry Finn".to_string(),
25//!     "My favorite book.".to_string(),
26//! );
27//! book_reviews.insert(
28//!     "Grimms' Fairy Tales".to_string(),
29//!     "Masterpiece.".to_string(),
30//! );
31//! book_reviews.insert(
32//!     "Pride and Prejudice".to_string(),
33//!     "Very enjoyable.".to_string(),
34//! );
35//! book_reviews.insert(
36//!     "The Adventures of Sherlock Holmes".to_string(),
37//!     "Eye lyked it alot.".to_string(),
38//! );
39//!
40//! // Check for a specific one.
41//! // When collections store owned values (String), they can still be
42//! // queried using references (&str).
43//! if !book_reviews.contains_key("Les Misérables") {
44//!     println!("We've got {} reviews, but Les Misérables ain't one.",
45//!              book_reviews.len());
46//! }
47//!
48//! // oops, this review has a lot of spelling mistakes, let's delete it.
49//! book_reviews.remove("The Adventures of Sherlock Holmes");
50//!
51//! // Look up the values associated with some keys.
52//! let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
53//! for &book in &to_find {
54//!     match book_reviews.get(book) {
55//!         Some(review) => println!("{book}: {review}"),
56//!         None => println!("{book} is unreviewed.")
57//!     }
58//! }
59//!
60//! // Look up the value for a key (will panic if the key is not found).
61//! println!("Review for Jane: {}", book_reviews["Pride and Prejudice"]);
62//!
63//! // Iterate over everything.
64//! for (book, review) in &book_reviews {
65//!     println!("{book}: \"{review}\"");
66//! }
67//! ```
68//!
69//! A `CompactMap` with a known list of items can be initialized from an array:
70//!
71//! ```
72//! use compact_map::CompactMap;
73//!
74//! // You need to specify the size of the map.
75//! let solar_distance = CompactMap::<_, _, 4>::from([
76//!     ("Mercury", 0.4),
77//!     ("Venus", 0.7),
78//!     ("Earth", 1.0),
79//!     ("Mars", 1.5),
80//! ]);
81//! ```
82//!
83//! `CompactMap` implements an [`Entry` API](CompactMap::entry), which allows
84//! for complex methods of getting, setting, updating and removing keys and
85//! their values:
86//!
87//! ```
88//! use compact_map::CompactMap;
89//!
90//! // type inference lets us omit an explicit type signature except for the capacity
91//! // (which would be `CompactMap<&str, u8, N>` in this example).
92//! let mut player_stats = CompactMap::<_, _, 5>::new();
93//!
94//! fn random_stat_buff() -> u8 {
95//!     // could actually return some random value here - let's just return
96//!     // some fixed value for now
97//!     42
98//! }
99//!
100//! // insert a key only if it doesn't already exist
101//! player_stats.entry("health").or_insert(100);
102//!
103//! // insert a key using a function that provides a new value only if it
104//! // doesn't already exist
105//! player_stats.entry("defence").or_insert_with(random_stat_buff);
106//!
107//! // update a key, guarding against the key possibly not being set
108//! let stat = player_stats.entry("attack").or_insert(100);
109//! *stat += random_stat_buff();
110//!
111//! // modify an entry before an insert with in-place mutation
112//! player_stats.entry("mana").and_modify(|mana| *mana += 200).or_insert(100);
113//! ```
114//!
115//! ## Optional Features
116//!
117//! ### `map_entry_replace`
118//!
119//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
120//!
121//! *This feature enables the `map_entry_replace` feature gate.*
122//!
123//! This feature enables the [`OccupiedEntry::replace_entry`] method,
124//! it makes operations that would otherwise require two look-ups into operations that require only one.
125//!
126//! Tracking issue: [rust-lang/rust#44286](https://github.com/rust-lang/rust/issues/44286)
127//!
128//! ### `extract_if`
129//!
130//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
131//!
132//! *This feature enables the `hash_extract_if` feature gate.*
133//!
134//! This feature enables the [`CompactMap::extract_if`] method,
135//! provides a draining, filtering iterator over the entries of a Map.
136//!
137//! Tracking issue: [rust-lang/rust#59618](https://github.com/rust-lang/rust/issues/59618)
138//!
139//! ### `entry_insert`
140//!
141//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
142//!
143//! *This feature enables the `entry_insert` feature gate.*
144//!
145//! This feature enables the [`Entry::insert_entry`] method.
146//!
147//! Tracking issue: [rust-lang/rust#65225](https://github.com/rust-lang/rust/issues/65225)
148//!
149//! ### `map_try_insert`
150//!
151//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
152//!
153//! *This feature enables the `map_try_insert` feature gate.*
154//!
155//! This feature enables the [`CompactMap::try_insert`] method.
156//!
157//! Tracking issue: [rust-lang/rust#82766](https://github.com/rust-lang/rust/issues/82766)
158//!
159//! ### `many_mut`
160//!
161//! **This feature is unstable and requires a nightly build of the Rust toolchain.**
162//!
163//! *This feature enables the `map_many_mut`, `get_many_mut` feature gate.*
164//!
165//! This feature enables the [`CompactMap::get_many_mut`], [`CompactMap::get_many_unchecked_mut`] methods.
166//!
167//! Tracking issue:
168//! - [rust-lang/rust#97601](https://github.com/rust-lang/rust/issues/97601)
169//! - [rust-lang/rust#104642](https://github.com/rust-lang/rust/issues/104642)
170
171#![deny(missing_docs)]
172#![allow(clippy::manual_map)]
173#![cfg_attr(docsrs, feature(doc_cfg))]
174#![cfg_attr(feature = "map_entry_replace", feature(map_entry_replace))] // issue 44286
175#![cfg_attr(feature = "extract_if", feature(hash_extract_if))] // issue 59618
176#![cfg_attr(feature = "entry_insert", feature(entry_insert))] // issue 65225
177#![cfg_attr(feature = "map_try_insert", feature(map_try_insert))] // issue 82766
178#![cfg_attr(feature = "many_mut", feature(map_many_mut))] // issue 97601
179#![cfg_attr(feature = "many_mut", feature(get_many_mut))] // issue 104642
180
181use std::borrow::Borrow;
182use std::collections::HashMap;
183use std::fmt;
184use std::fmt::Debug;
185use std::hash::{BuildHasher, Hash};
186use std::iter::FusedIterator;
187use std::ops::Index;
188
189mod base;
190mod utils;
191#[cfg(feature = "map_try_insert")]
192pub use base::entry::OccupiedError;
193pub use base::{
194    entry::{Entry, OccupiedEntry, VacantEntry},
195    TryReserveError,
196};
197
198const DEFAULT_MAX_INLINE_ENTRIES: usize = 16;
199
200/// A map that inlines entries to avoid heap allocations for small maps.
201pub struct CompactMap<K, V, const N: usize> {
202    base: base::MapImpl<K, V, N>,
203}
204
205impl<K, V, const N: usize> CompactMap<K, V, N> {
206    /// Creates an empty `CompactMap`.
207    ///
208    /// The compact map will be able to hold up to `N` entries without spilling to the heap.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// use compact_map::CompactMap;
214    /// let mut map: CompactMap<&str, i32, 16> = CompactMap::new();
215    /// ```
216    #[inline(always)]
217    #[must_use]
218    pub const fn new() -> Self {
219        Self {
220            base: base::MapImpl::new(),
221        }
222    }
223
224    /// Returns `true` if the data has spilled into an std `HashMap`.
225    ///
226    /// ```
227    /// use compact_map::CompactMap;
228    ///
229    /// let mut map: CompactMap<i32, i32, 2>  = CompactMap::new();
230    /// assert!(!map.spilled());
231    ///
232    /// map.insert(1, 2);
233    /// map.insert(3, 4);
234    /// map.insert(5, 6);
235    /// assert!(map.spilled());
236    /// ```
237    #[inline(always)]
238    pub const fn spilled(&self) -> bool {
239        self.base.spilled()
240    }
241
242    /// Returns the number of elements the map can hold without reallocating.
243    ///
244    /// When spilled, this number is a lower bound;
245    /// the `CompactMap<K, V>` might be able to hold more,
246    /// but is guaranteed to be able to hold at least this many.
247    ///
248    /// # Examples
249    ///
250    /// ```
251    /// use compact_map::CompactMap;
252    /// let map: CompactMap<i32, i32, 100> = CompactMap::new();
253    /// assert!(map.capacity() >= 100);
254    /// ```
255    #[inline(always)]
256    pub fn capacity(&self) -> usize {
257        self.base.capacity()
258    }
259
260    /// An iterator visiting all keys in arbitrary order.
261    /// The iterator element type is `&'a K`.
262    ///
263    /// # Examples
264    ///
265    /// ```
266    /// use compact_map::CompactMap;
267    ///
268    /// let map: CompactMap<&str, i32, 3> = CompactMap::from([
269    ///     ("a", 1),
270    ///     ("b", 2),
271    ///     ("c", 3),
272    /// ]);
273    ///
274    /// for key in map.keys() {
275    ///     println!("{key}");
276    /// }
277    /// ```
278    ///
279    /// # Performance
280    ///
281    /// - When heapless: iterating over keys takes O(len) time.
282    /// - When spilled: as per docs in [HashMap::keys], iterating over keys takes O(capacity) time.
283    #[inline]
284    pub fn keys(&self) -> Keys<'_, K, V, N> {
285        Keys {
286            inner: self.base.iter(),
287        }
288    }
289
290    /// Creates a consuming iterator visiting all the keys in arbitrary order.
291    /// The map cannot be used after calling this.
292    /// The iterator element type is `K`.
293    ///
294    /// # Examples
295    ///
296    /// ```
297    /// use compact_map::CompactMap;
298    ///
299    /// let map: CompactMap<&str, i32, 3> = CompactMap::from([
300    ///     ("a", 1),
301    ///     ("b", 2),
302    ///     ("c", 3),
303    /// ]);
304    ///
305    /// let mut vec: Vec<&str> = map.into_keys().collect();
306    /// // The `IntoKeys` iterator produces keys in arbitrary order, so the
307    /// // keys must be sorted to test them against a sorted array.
308    /// vec.sort_unstable();
309    /// assert_eq!(vec, ["a", "b", "c"]);
310    /// ```
311    ///
312    /// # Performance
313    ///
314    /// - When heapless: iterating over keys takes O(len) time.
315    /// - When spilled: as per in [std docs](HashMap::keys), iterating over keys takes O(capacity) time.
316    #[inline]
317    pub fn into_keys(self) -> IntoKeys<K, V, N> {
318        IntoKeys {
319            inner: self.base.into_iter(),
320        }
321    }
322
323    /// An iterator visiting all values in arbitrary order.
324    /// The iterator element type is `&'a V`.
325    ///
326    /// # Examples
327    ///
328    /// ```
329    /// use compact_map::CompactMap;
330    ///
331    /// let map: CompactMap<&str, i32, 3> = CompactMap::from([
332    ///     ("a", 1),
333    ///     ("b", 2),
334    ///     ("c", 3),
335    /// ]);
336    ///
337    /// for val in map.values() {
338    ///     println!("{val}");
339    /// }
340    /// ```
341    ///
342    /// # Performance
343    ///
344    /// - When heapless: iterating over keys takes O(len) time.
345    /// - When spilled: as per in [std docs](HashMap::keys), iterating over keys takes O(capacity) time.
346    pub fn values(&self) -> Values<'_, K, V, N> {
347        Values {
348            base: self.base.iter(),
349        }
350    }
351
352    /// An iterator visiting all values mutably in arbitrary order.
353    /// The iterator element type is `&'a mut V`.
354    ///
355    /// # Examples
356    ///
357    /// ```
358    /// use compact_map::CompactMap;
359    ///
360    /// let mut map: CompactMap<&str, i32, 3> = CompactMap::from([
361    ///     ("a", 1),
362    ///     ("b", 2),
363    ///     ("c", 3),
364    /// ]);
365    ///
366    /// for val in map.values_mut() {
367    ///     *val = *val + 10;
368    /// }
369    ///
370    /// for val in map.values() {
371    ///     println!("{val}");
372    /// }
373    /// ```
374    ///
375    /// # Performance
376    ///
377    /// - When heapless: iterating over keys takes O(len) time.
378    /// - When spilled: as per in [std docs](HashMap::keys), iterating over keys takes O(capacity) time.
379    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V, N> {
380        ValuesMut {
381            inner: self.base.iter_mut(),
382        }
383    }
384
385    /// Creates a consuming iterator visiting all the values in arbitrary order.
386    /// The map cannot be used after calling this.
387    /// The iterator element type is `V`.
388    ///
389    /// # Examples
390    ///
391    /// ```
392    /// use compact_map::CompactMap;
393    ///
394    /// let mut map: CompactMap<&str, i32, 3> = CompactMap::from([
395    ///     ("a", 1),
396    ///     ("b", 2),
397    ///     ("c", 3),
398    /// ]);
399    ///
400    /// let mut vec: Vec<i32> = map.into_values().collect();
401    /// // The `IntoValues` iterator produces values in arbitrary order, so
402    /// // the values must be sorted to test them against a sorted array.
403    /// vec.sort_unstable();
404    /// assert_eq!(vec, [1, 2, 3]);
405    /// ```
406    ///
407    /// # Performance
408    ///
409    /// - When heapless: iterating over keys takes O(len) time.
410    /// - When spilled: as per in [std docs](HashMap::keys), iterating over keys takes O(capacity) time.
411    #[inline]
412    pub fn into_values(self) -> IntoValues<K, V, N> {
413        IntoValues {
414            inner: self.base.into_iter(),
415        }
416    }
417
418    /// An iterator visiting all key-value pairs in arbitrary order.
419    /// The iterator element type is `(&'a K, &'a V)`.
420    ///
421    /// # Examples
422    ///
423    /// ```
424    /// use compact_map::CompactMap;
425    ///
426    /// let map: CompactMap<&str, i32, 3> = CompactMap::from([
427    ///     ("a", 1),
428    ///     ("b", 2),
429    ///     ("c", 3),
430    /// ]);
431    ///
432    /// for (key, val) in map.iter() {
433    ///     println!("key: {key} val: {val}");
434    /// }
435    /// ```
436    ///
437    /// # Performance
438    ///
439    /// - When heapless: iterating over keys takes O(len) time.
440    /// - When spilled: as per in [std docs](HashMap::keys), iterating over keys takes O(capacity) time.
441    #[inline]
442    pub fn iter(&self) -> Iter<'_, K, V, N> {
443        Iter {
444            base: self.base.iter(),
445        }
446    }
447
448    /// An iterator visiting all key-value pairs in arbitrary order,
449    /// with mutable references to the values.
450    /// The iterator element type is `(&'a K, &'a mut V)`.
451    ///
452    /// # Examples
453    ///
454    /// ```
455    /// use compact_map::CompactMap;
456    ///
457    /// let mut map: CompactMap<&str, i32, 3> = CompactMap::from([
458    ///     ("a", 1),
459    ///     ("b", 2),
460    ///     ("c", 3),
461    /// ]);
462    ///
463    /// // Update all values
464    /// for (_, val) in map.iter_mut() {
465    ///     *val *= 2;
466    /// }
467    ///
468    /// for (key, val) in &map {
469    ///     println!("key: {key} val: {val}");
470    /// }
471    /// ```
472    ///
473    /// # Performance
474    ///
475    /// - When heapless: iterating over keys takes O(len) time.
476    /// - When spilled: as per in [std docs](HashMap::keys), iterating over keys takes O(capacity) time.
477    pub fn iter_mut(&mut self) -> IterMut<'_, K, V, N> {
478        IterMut {
479            base: self.base.iter_mut(),
480        }
481    }
482
483    /// Returns the number of elements in the map.
484    ///
485    /// # Examples
486    ///
487    /// ```
488    /// use compact_map::CompactMap;
489    ///
490    /// let mut a = CompactMap::default();
491    /// assert_eq!(a.len(), 0);
492    /// a.insert(1, "a");
493    /// assert_eq!(a.len(), 1);
494    /// ```
495    pub fn len(&self) -> usize {
496        self.base.len()
497    }
498
499    /// Returns `true` if the map contains no elements.
500    ///
501    /// # Examples
502    ///
503    /// ```
504    /// use compact_map::CompactMap;
505    ///
506    /// let mut a = CompactMap::default();
507    /// assert!(a.is_empty());
508    /// a.insert(1, "a");
509    /// assert!(!a.is_empty());
510    /// ```
511    #[inline]
512    pub fn is_empty(&self) -> bool {
513        self.base.is_empty()
514    }
515
516    /// Clears the map, returning all key-value pairs as an iterator. Keeps the
517    /// allocated memory for reuse.
518    ///
519    /// If the returned iterator is dropped before being fully consumed, it
520    /// drops the remaining key-value pairs. The returned iterator keeps a
521    /// mutable borrow on the map to optimize its implementation.
522    ///
523    /// # Examples
524    ///
525    /// ```
526    /// use compact_map::CompactMap;
527    ///
528    /// let mut a = CompactMap::default();
529    /// a.insert(1, "a");
530    /// a.insert(2, "b");
531    ///
532    /// for (k, v) in a.drain().take(1) {
533    ///     assert!(k == 1 || k == 2);
534    ///     assert!(v == "a" || v == "b");
535    /// }
536    ///
537    /// assert!(a.is_empty());
538    /// ```
539    #[inline]
540    pub fn drain(&mut self) -> Drain<'_, K, V, N> {
541        Drain {
542            base: self.base.drain(),
543        }
544    }
545
546    /// Creates an iterator which uses a closure to determine if an element should be removed.
547    ///
548    /// If the closure returns true, the element is removed from the map and yielded.
549    /// If the closure returns false, or panics, the element remains in the map and will not be
550    /// yielded.
551    ///
552    /// Note that `extract_if` lets you mutate every value in the filter closure, regardless of
553    /// whether you choose to keep or remove it.
554    ///
555    /// If the returned `ExtractIf` is not exhausted, e.g. because it is dropped without iterating
556    /// or the iteration short-circuits, then the remaining elements will be retained.
557    /// Use [`retain`] with a negated predicate if you do not need the returned iterator.
558    ///
559    /// [`retain`]: CompactMap::retain
560    ///
561    /// # Examples
562    ///
563    /// Splitting a map into even and odd keys, reusing the original map:
564    ///
565    /// ```
566    /// use compact_map::CompactMap;
567    ///
568    /// let mut map: CompactMap<i32, i32, 8> = (0..8).map(|x| (x, x)).collect();
569    /// let extracted: CompactMap<i32, i32, 8> = map.extract_if(|k, _v| k % 2 == 0).collect();
570    ///
571    /// let mut evens = extracted.keys().copied().collect::<Vec<_>>();
572    /// let mut odds = map.keys().copied().collect::<Vec<_>>();
573    /// evens.sort();
574    /// odds.sort();
575    ///
576    /// assert_eq!(evens, vec![0, 2, 4, 6]);
577    /// assert_eq!(odds, vec![1, 3, 5, 7]);
578    /// ```
579    #[cfg_attr(docsrs, doc(cfg(feature = "extract_if")))]
580    #[cfg(feature = "extract_if")]
581    #[inline]
582    pub fn extract_if<F>(&mut self, pred: F) -> ExtractIf<'_, K, V, F, N>
583    where
584        F: FnMut(&K, &mut V) -> bool,
585    {
586        ExtractIf {
587            base: self.base.extract_if(pred),
588        }
589    }
590
591    /// Retains only the elements specified by the predicate.
592    ///
593    /// In other words, remove all pairs `(k, v)` for which `f(&k, &mut v)` returns `false`.
594    /// The elements are visited in unsorted (and unspecified) order.
595    ///
596    /// # Examples
597    ///
598    /// ```
599    /// use compact_map::CompactMap;
600    ///
601    /// let mut map: CompactMap<i32, i32, 16> = (0..8).map(|x| (x, x*10)).collect();
602    /// map.retain(|&k, _| k % 2 == 0);
603    /// assert_eq!(map.len(), 4);
604    /// ```
605    ///
606    /// # Performance
607    ///
608    /// - When heapless: iterating over keys takes O(len) time.
609    /// - When spilled: as per in [std docs](HashMap::keys), iterating over keys takes O(capacity) time.
610    #[inline]
611    pub fn retain<F>(&mut self, f: F)
612    where
613        F: FnMut(&K, &mut V) -> bool,
614    {
615        self.base.retain(f)
616    }
617
618    /// Clears the map, removing all key-value pairs. Keeps the allocated memory
619    /// for reuse.
620    ///
621    /// # Examples
622    ///
623    /// ```
624    /// use compact_map::CompactMap;
625    ///
626    /// let mut a = CompactMap::default();
627    /// a.insert(1, "a");
628    /// a.clear();
629    /// assert!(a.is_empty());
630    /// ```
631    #[inline]
632    pub fn clear(&mut self) {
633        self.base.clear();
634    }
635}
636
637impl<K, V, const N: usize> CompactMap<K, V, N>
638where
639    K: Eq + Hash,
640{
641    /// Reserves capacity for at least `additional` more elements to be inserted
642    /// in the `CompactMap`. The collection may reserve more space to speculatively
643    /// avoid frequent reallocations. After calling `reserve`,
644    /// capacity will be greater than or equal to `self.len() + additional`.
645    /// Does nothing if capacity is already sufficient.
646    ///
647    /// If current variant is heapless and `self.len() + additional` is greater than `N`,
648    /// the map will spill to [`HashMap`] immediately; otherwise, it's a no-op.
649    ///
650    /// # Panics
651    ///
652    /// Panics if the new allocation size overflows [`usize`].
653    ///
654    /// # Examples
655    ///
656    /// ```
657    /// use compact_map::CompactMap;
658    /// let mut map: CompactMap<&str, i32, 16> = CompactMap::new();
659    /// map.reserve(32);
660    /// assert!(map.capacity() >= 32);
661    /// assert!(map.spilled());
662    /// ```
663    #[inline]
664    pub fn reserve(&mut self, additional: usize) {
665        self.base.reserve(additional)
666    }
667
668    /// Tries to reserve capacity for at least `additional` more elements to be inserted
669    /// in the `HashMap`. The collection may reserve more space to speculatively
670    /// avoid frequent reallocations. After calling `try_reserve`,
671    /// capacity will be greater than or equal to `self.len() + additional` if
672    /// it returns `Ok(())`.
673    /// Does nothing if capacity is already sufficient.
674    ///
675    /// If current variant is heapless and `self.len() + additional` is greater than `N`,
676    /// the map will spill to [`HashMap`] immediately; otherwise, it's a no-op.
677    ///
678    /// # Errors
679    ///
680    /// If the capacity overflows, or the allocator reports a failure, then an error
681    /// is returned.
682    ///
683    /// # Examples
684    ///
685    /// ```
686    /// use compact_map::CompactMap;
687    /// let mut map: CompactMap<&str, i32, 16> = CompactMap::new();
688    ///
689    /// map.try_reserve(10).expect("why is the test harness OOMing on a handful of bytes?");
690    /// ```
691    #[inline]
692    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
693        self.base.try_reserve(additional)
694    }
695
696    /// Manually spills to a [`HashMap`].
697    ///
698    /// # Examples
699    ///
700    /// ```
701    /// use compact_map::CompactMap;
702    /// let mut map: CompactMap<i32, i32, 16> = CompactMap::new();
703    /// map.spill();
704    /// assert!(map.spilled());
705    #[inline]
706    pub fn spill(&mut self) {
707        self.base.spill()
708    }
709
710    /// Shrinks the map into a heapless map with capacity `M`.
711    ///
712    /// # Errors
713    ///
714    /// If `M` is less than the current length of the map, the original map is returned.
715    ///
716    /// # Examples
717    ///
718    /// ```
719    /// use compact_map::CompactMap;
720    ///
721    /// let mut map: CompactMap<i32, i32, 16> = CompactMap::new();
722    /// map.insert(1, 2);
723    /// map.insert(3, 4);
724    /// let map = map.shrink_into_heapless::<2>().unwrap();
725    /// ```
726    #[inline]
727    pub fn shrink_into_heapless<const M: usize>(
728        self,
729    ) -> Result<CompactMap<K, V, M>, CompactMap<K, V, N>> {
730        self.base
731            .shrink_into_heapless()
732            .map(|base| CompactMap { base })
733            .map_err(|base| CompactMap { base })
734    }
735
736    /// This is a proxy to the underlying [`HashMap::shrink_to_fit`] method.
737    /// And it's a no-op if the map is heapless.
738    ///
739    /// Shrinks the capacity of the map as much as possible. It will drop
740    /// down as much as possible while maintaining the internal rules
741    /// and possibly leaving some space in accordance with the resize policy.
742    ///
743    /// # Examples
744    ///
745    /// ```
746    /// use compact_map::CompactMap;
747    ///
748    /// let mut map: CompactMap<i32, i32, 10> = CompactMap::new();
749    /// map.reserve(90);
750    /// map.insert(1, 2);
751    /// map.insert(3, 4);
752    /// assert!(map.capacity() >= 100);
753    /// map.shrink_to_fit();
754    /// assert!(map.capacity() >= 2);
755    /// ```
756    #[inline]
757    pub fn shrink_to_fit(&mut self) {
758        self.base.shrink_to_fit();
759    }
760
761    /// This is a proxy to the underlying [`HashMap::shrink_to`] method.
762    /// And it's a no-op if the map is heapless.
763    ///
764    /// Shrinks the capacity of the map with a lower limit. It will drop
765    /// down no lower than the supplied limit while maintaining the internal rules
766    /// and possibly leaving some space in accordance with the resize policy.
767    ///
768    /// If the current capacity is less than the lower limit, this is a no-op.
769    ///
770    /// # Examples
771    ///
772    /// ```
773    /// use compact_map::CompactMap;
774    ///
775    /// let mut map: CompactMap<i32, i32, 10> = CompactMap::new();
776    /// map.reserve(90);
777    /// map.insert(1, 2);
778    /// map.insert(3, 4);
779    /// assert!(map.capacity() >= 100);
780    /// map.shrink_to(10);
781    /// assert!(map.capacity() >= 10);
782    /// map.shrink_to(0);
783    /// assert!(map.capacity() >= 2);
784    /// ```
785    #[inline]
786    pub fn shrink_to(&mut self, min_capacity: usize) {
787        self.base.shrink_to(min_capacity);
788    }
789
790    /// Gets the given key's corresponding entry in the map for in-place manipulation.
791    ///
792    /// # Examples
793    ///
794    /// ```
795    /// use compact_map::CompactMap;
796    ///
797    /// let mut letters = CompactMap::default();
798    ///
799    /// for ch in "a short treatise on fungi".chars() {
800    ///     letters.entry(ch).and_modify(|counter| *counter += 1).or_insert(1);
801    /// }
802    ///
803    /// assert_eq!(letters[&'s'], 2);
804    /// assert_eq!(letters[&'t'], 3);
805    /// assert_eq!(letters[&'u'], 1);
806    /// assert_eq!(letters.get(&'y'), None);
807    /// ```
808    #[inline]
809    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, N> {
810        self.base.entry(key)
811    }
812
813    /// Returns a reference to the value corresponding to the key.
814    ///
815    /// The key may be any borrowed form of the map's key type, but
816    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
817    /// the key type.
818    ///
819    /// # Examples
820    ///
821    /// ```
822    /// use compact_map::CompactMap;
823    ///
824    /// let mut map = CompactMap::default();
825    /// map.insert(1, "a");
826    /// assert_eq!(map.get(&1), Some(&"a"));
827    /// assert_eq!(map.get(&2), None);
828    /// ```
829    #[inline]
830    pub fn get<Q>(&self, k: &Q) -> Option<&V>
831    where
832        K: Borrow<Q>,
833        Q: Hash + Eq + ?Sized,
834    {
835        self.base.get(k)
836    }
837
838    /// Returns the key-value pair corresponding to the supplied key.
839    ///
840    /// The supplied key may be any borrowed form of the map's key type, but
841    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
842    /// the key type.
843    ///
844    /// # Examples
845    ///
846    /// ```
847    /// use compact_map::CompactMap;
848    ///
849    /// let mut map = CompactMap::default();
850    /// map.insert(1, "a");
851    /// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
852    /// assert_eq!(map.get_key_value(&2), None);
853    /// ```
854    #[inline]
855    pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
856    where
857        K: Borrow<Q>,
858        Q: Hash + Eq + ?Sized,
859    {
860        self.base.get_key_value(k)
861    }
862
863    /// Attempts to get mutable references to `N` values in the map at once.
864    ///
865    /// Returns an array of length `N` with the results of each query. For soundness, at most one
866    /// mutable reference will be returned to any value. `None` will be returned if any of the
867    /// keys are duplicates or missing.
868    ///
869    /// # Examples
870    ///
871    /// ```
872    /// use compact_map::CompactMap;
873    ///
874    /// let mut libraries = CompactMap::default();
875    /// libraries.insert("Bodleian Library".to_string(), 1602);
876    /// libraries.insert("Athenæum".to_string(), 1807);
877    /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
878    /// libraries.insert("Library of Congress".to_string(), 1800);
879    ///
880    /// let got = libraries.get_many_mut([
881    ///     "Athenæum",
882    ///     "Library of Congress",
883    /// ]);
884    /// assert_eq!(
885    ///     got,
886    ///     Some([
887    ///         &mut 1807,
888    ///         &mut 1800,
889    ///     ]),
890    /// );
891    ///
892    /// // Missing keys result in None
893    /// let got = libraries.get_many_mut([
894    ///     "Athenæum",
895    ///     "New York Public Library",
896    /// ]);
897    /// assert_eq!(got, None);
898    ///
899    /// // Duplicate keys result in None
900    /// let got = libraries.get_many_mut([
901    ///     "Athenæum",
902    ///     "Athenæum",
903    /// ]);
904    /// assert_eq!(got, None);
905    /// ```
906    #[cfg_attr(docsrs, doc(cfg(feature = "many_mut")))]
907    #[cfg(feature = "many_mut")]
908    #[inline]
909    pub fn get_many_mut<Q, const M: usize>(&mut self, ks: [&Q; M]) -> Option<[&'_ mut V; M]>
910    where
911        K: Borrow<Q>,
912        Q: Hash + Eq + ?Sized,
913    {
914        self.base.get_many_mut(ks)
915    }
916
917    /// Attempts to get mutable references to `N` values in the map at once, without validating that
918    /// the values are unique.
919    ///
920    /// Returns an array of length `N` with the results of each query. `None` will be returned if
921    /// any of the keys are missing.
922    ///
923    /// For a safe alternative see [`get_many_mut`](Self::get_many_mut).
924    ///
925    /// # Safety
926    ///
927    /// Calling this method with overlapping keys is *[undefined behavior]* even if the resulting
928    /// references are not used.
929    ///
930    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
931    ///
932    /// # Examples
933    ///
934    /// ```
935    /// use compact_map::CompactMap;
936    ///
937    /// let mut libraries = CompactMap::default();
938    /// libraries.insert("Bodleian Library".to_string(), 1602);
939    /// libraries.insert("Athenæum".to_string(), 1807);
940    /// libraries.insert("Herzogin-Anna-Amalia-Bibliothek".to_string(), 1691);
941    /// libraries.insert("Library of Congress".to_string(), 1800);
942    ///
943    /// let got = libraries.get_many_mut([
944    ///     "Athenæum",
945    ///     "Library of Congress",
946    /// ]);
947    /// assert_eq!(
948    ///     got,
949    ///     Some([
950    ///         &mut 1807,
951    ///         &mut 1800,
952    ///     ]),
953    /// );
954    ///
955    /// // Missing keys result in None
956    /// let got = libraries.get_many_mut([
957    ///     "Athenæum",
958    ///     "New York Public Library",
959    /// ]);
960    /// assert_eq!(got, None);
961    /// ```
962    #[cfg_attr(docsrs, doc(cfg(feature = "many_mut")))]
963    #[cfg(feature = "many_mut")]
964    #[inline]
965    pub unsafe fn get_many_unchecked_mut<Q, const M: usize>(
966        &mut self,
967        ks: [&Q; M],
968    ) -> Option<[&'_ mut V; M]>
969    where
970        K: Borrow<Q>,
971        Q: Hash + Eq + ?Sized,
972    {
973        self.base.get_many_unchecked_mut(ks)
974    }
975
976    /// Returns `true` if the map contains a value for the specified key.
977    ///
978    /// The key may be any borrowed form of the map's key type, but
979    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
980    /// the key type.
981    ///
982    /// # Examples
983    ///
984    /// ```
985    /// use compact_map::CompactMap;
986    ///
987    /// let mut map = CompactMap::default();
988    /// map.insert(1, "a");
989    /// assert_eq!(map.contains_key(&1), true);
990    /// assert_eq!(map.contains_key(&2), false);
991    /// ```
992    #[inline]
993    pub fn contains_key<Q>(&self, k: &Q) -> bool
994    where
995        K: Borrow<Q>,
996        Q: Hash + Eq + ?Sized,
997    {
998        self.base.contains_key(k)
999    }
1000
1001    /// Returns a mutable reference to the value corresponding to the key.
1002    ///
1003    /// The key may be any borrowed form of the map's key type, but
1004    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1005    /// the key type.
1006    ///
1007    /// # Examples
1008    ///
1009    /// ```
1010    /// use compact_map::CompactMap;
1011    ///
1012    /// let mut map = CompactMap::default();
1013    /// map.insert(1, "a");
1014    /// if let Some(x) = map.get_mut(&1) {
1015    ///     *x = "b";
1016    /// }
1017    /// assert_eq!(map[&1], "b");
1018    /// ```
1019    #[inline]
1020    pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
1021    where
1022        K: Borrow<Q>,
1023        Q: Hash + Eq + ?Sized,
1024    {
1025        self.base.get_mut(k)
1026    }
1027
1028    /// Inserts a key-value pair into the map.
1029    ///
1030    /// If the map did not have this key present, [`None`] is returned.
1031    ///
1032    /// If the map did have this key present, the value is updated, and the old
1033    /// value is returned. The key is not updated, though; this matters for
1034    /// types that can be `==` without being identical. See the [module-level
1035    /// documentation] for more.
1036    ///
1037    /// # Examples
1038    ///
1039    /// ```
1040    /// use compact_map::CompactMap;
1041    ///
1042    /// let mut map = CompactMap::default();
1043    /// assert_eq!(map.insert(37, "a"), None);
1044    /// assert_eq!(map.is_empty(), false);
1045    ///
1046    /// map.insert(37, "b");
1047    /// assert_eq!(map.insert(37, "c"), Some("b"));
1048    /// assert_eq!(map[&37], "c");
1049    /// ```
1050    #[inline]
1051    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
1052        self.base.insert(k, v)
1053    }
1054
1055    /// Tries to insert a key-value pair into the map, and returns
1056    /// a mutable reference to the value in the entry.
1057    ///
1058    /// If the map already had this key present, nothing is updated, and
1059    /// an error containing the occupied entry and the value is returned.
1060    ///
1061    /// # Examples
1062    ///
1063    /// Basic usage:
1064    ///
1065    /// ```
1066    /// use compact_map::CompactMap;
1067    ///
1068    /// let mut map = CompactMap::default();
1069    /// assert_eq!(map.try_insert(37, "a").unwrap(), &"a");
1070    ///
1071    /// let err = map.try_insert(37, "b").unwrap_err();
1072    /// assert_eq!(err.entry.key(), &37);
1073    /// assert_eq!(err.entry.get(), &"a");
1074    /// assert_eq!(err.value, "b");
1075    /// ```
1076    #[cfg_attr(docsrs, doc(cfg(feature = "map_try_insert")))]
1077    #[cfg(feature = "map_try_insert")]
1078    pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, N>> {
1079        match self.entry(key) {
1080            Entry::Occupied(entry) => Err(OccupiedError { entry, value }),
1081            Entry::Vacant(entry) => Ok(entry.insert(value)),
1082        }
1083    }
1084
1085    /// Removes a key from the map, returning the value at the key if the key
1086    /// was previously in the map.
1087    ///
1088    /// The key may be any borrowed form of the map's key type, but
1089    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1090    /// the key type.
1091    ///
1092    /// # Examples
1093    ///
1094    /// ```
1095    /// use compact_map::CompactMap;
1096    ///
1097    /// let mut map = CompactMap::default();
1098    /// map.insert(1, "a");
1099    /// assert_eq!(map.remove(&1), Some("a"));
1100    /// assert_eq!(map.remove(&1), None);
1101    /// ```
1102    #[inline]
1103    pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
1104    where
1105        K: Borrow<Q>,
1106        Q: Hash + Eq + ?Sized,
1107    {
1108        self.base.remove(k)
1109    }
1110
1111    /// Removes a key from the map, returning the stored key and value if the
1112    /// key was previously in the map.
1113    ///
1114    /// The key may be any borrowed form of the map's key type, but
1115    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
1116    /// the key type.
1117    ///
1118    /// # Examples
1119    ///
1120    /// ```
1121    /// use compact_map::CompactMap;
1122    ///
1123    /// # fn main() {
1124    /// let mut map = CompactMap::default();
1125    /// map.insert(1, "a");
1126    /// assert_eq!(map.remove_entry(&1), Some((1, "a")));
1127    /// assert_eq!(map.remove(&1), None);
1128    /// # }
1129    /// ```
1130    #[inline]
1131    pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
1132    where
1133        K: Borrow<Q>,
1134        Q: Hash + Eq + ?Sized,
1135    {
1136        self.base.remove_entry(k)
1137    }
1138
1139    /// Converts the map into a [`HashMap`].
1140    ///
1141    /// If the map has spilled into a `HashMap`, this will return that `HashMap`.
1142    /// Otherwise, it will create a new `HashMap` and move all the entries into it.
1143    #[inline]
1144    pub fn into_hashmap(self) -> HashMap<K, V> {
1145        self.base.into_hashmap()
1146    }
1147
1148    /// Converts the map into a [`HashMap`] with a given hasher.
1149    ///
1150    /// This will always create a new `HashMap` and move all the entries into it.
1151    ///
1152    /// See also [`HashMap::with_hasher`].
1153    #[inline]
1154    pub fn into_hashmap_with_hasher<S: BuildHasher>(self, hash_builder: S) -> HashMap<K, V, S> {
1155        let mut map = HashMap::with_capacity_and_hasher(self.len(), hash_builder);
1156        map.extend(self.base);
1157        map
1158    }
1159
1160    /// Converts the map into a [`HashMap`] with at least the specified capacity, using
1161    /// `hasher` to hash the keys. The capacity will always be at least `self.len()`.
1162    ///
1163    /// This will always create a new `HashMap` and move all the entries into it.
1164    ///
1165    /// See also [`HashMap::with_capacity_and_hasher`].
1166    #[inline]
1167    pub fn into_hashmap_with_capacity_and_hasher<S: BuildHasher>(
1168        self,
1169        capacity: usize,
1170        hash_builder: S,
1171    ) -> HashMap<K, V, S> {
1172        let mut map = HashMap::with_capacity_and_hasher(capacity.max(self.len()), hash_builder);
1173        map.extend(self.base);
1174        map
1175    }
1176}
1177
1178impl<K, V, const N: usize, const M: usize> PartialEq<CompactMap<K, V, M>> for CompactMap<K, V, N>
1179where
1180    K: Eq + Hash,
1181    V: PartialEq,
1182{
1183    fn eq(&self, other: &CompactMap<K, V, M>) -> bool {
1184        if self.len() != other.len() {
1185            return false;
1186        }
1187
1188        self.iter()
1189            .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v))
1190    }
1191}
1192
1193impl<K, V, const N: usize> Eq for CompactMap<K, V, N>
1194where
1195    K: Eq + Hash,
1196    V: Eq,
1197{
1198}
1199
1200impl<K, V, const N: usize> Debug for CompactMap<K, V, N>
1201where
1202    K: Debug,
1203    V: Debug,
1204{
1205    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1206        f.debug_map().entries(self.iter()).finish()
1207    }
1208}
1209
1210impl<K, V> Default for CompactMap<K, V, DEFAULT_MAX_INLINE_ENTRIES> {
1211    fn default() -> Self {
1212        Self::new()
1213    }
1214}
1215
1216impl<K, Q: ?Sized, V, const N: usize> Index<&Q> for CompactMap<K, V, N>
1217where
1218    K: Eq + Hash + Borrow<Q>,
1219    Q: Eq + Hash,
1220{
1221    type Output = V;
1222
1223    /// Returns a reference to the value corresponding to the supplied key.
1224    ///
1225    /// # Panics
1226    ///
1227    /// Panics if the key is not present in the `CompactMap`.
1228    #[inline]
1229    fn index(&self, key: &Q) -> &V {
1230        self.get(key).expect("no entry found for key")
1231    }
1232}
1233
1234impl<K, V, const N: usize, const M: usize> From<[(K, V); N]> for CompactMap<K, V, M>
1235where
1236    K: Eq + Hash,
1237{
1238    /// # Examples
1239    ///
1240    /// ```
1241    /// use compact_map::CompactMap;
1242    ///
1243    /// let map1: CompactMap<i32, i32, 16> = CompactMap::from([(1, 2), (3, 4)]);
1244    /// let map2: CompactMap<i32, i32, 32> = [(1, 2), (3, 4)].into();
1245    /// assert_eq!(map1, map2);
1246    /// ```
1247    fn from(arr: [(K, V); N]) -> Self {
1248        Self {
1249            base: base::MapImpl::from(arr),
1250        }
1251    }
1252}
1253
1254/// An iterator over the keys of a `CompactMap`.
1255///
1256/// This `struct` is created by the [`keys`] method on [`CompactMap`]. See its
1257/// documentation for more.
1258///
1259/// [`keys`]: CompactMap::keys
1260///
1261/// # Example
1262///
1263/// ```
1264/// use compact_map::CompactMap;
1265///
1266/// let map: CompactMap<&str, i32, 16> = CompactMap::from([
1267///     ("a", 1),
1268/// ]);
1269/// let iter_keys = map.keys();
1270/// ```
1271pub struct Keys<'a, K, V, const N: usize> {
1272    pub(crate) inner: base::iter::IterInner<'a, K, V, N>,
1273}
1274
1275impl<K, V, const N: usize> Clone for Keys<'_, K, V, N> {
1276    fn clone(&self) -> Self {
1277        Self {
1278            inner: self.inner.clone(),
1279        }
1280    }
1281}
1282
1283impl<K: Debug, V, const N: usize> Debug for Keys<'_, K, V, N> {
1284    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1285        f.debug_list().entries(self.clone()).finish()
1286    }
1287}
1288
1289impl<'a, K, V, const N: usize> Iterator for Keys<'a, K, V, N> {
1290    type Item = &'a K;
1291
1292    #[inline]
1293    fn next(&mut self) -> Option<&'a K> {
1294        self.inner.next().map(|(k, _)| k)
1295    }
1296    #[inline]
1297    fn size_hint(&self) -> (usize, Option<usize>) {
1298        self.inner.size_hint()
1299    }
1300    #[inline]
1301    fn count(self) -> usize {
1302        self.inner.len()
1303    }
1304    #[inline]
1305    fn fold<B, F>(self, init: B, mut f: F) -> B
1306    where
1307        Self: Sized,
1308        F: FnMut(B, Self::Item) -> B,
1309    {
1310        self.inner.fold(init, |acc, (k, _)| f(acc, k))
1311    }
1312}
1313impl<K, V, const N: usize> ExactSizeIterator for Keys<'_, K, V, N> {
1314    #[inline]
1315    fn len(&self) -> usize {
1316        self.inner.len()
1317    }
1318}
1319impl<K, V, const N: usize> FusedIterator for Keys<'_, K, V, N> {}
1320
1321/// An owning iterator over the keys of a `CompactMap`.
1322///
1323/// This `struct` is created by the [`into_keys`] method on [`CompactMap`].
1324/// See its documentation for more.
1325///
1326/// [`into_keys`]: CompactMap::into_keys
1327///
1328/// # Example
1329///
1330/// ```
1331/// use compact_map::CompactMap;
1332///
1333/// let map: CompactMap<&str, i32, 16> = CompactMap::from([
1334///     ("a", 1),
1335/// ]);
1336/// let iter_keys = map.into_keys();
1337/// ```
1338pub struct IntoKeys<K, V, const N: usize> {
1339    pub(crate) inner: base::iter::IntoIterInner<K, V, N>,
1340}
1341
1342impl<K, V, const N: usize> Iterator for IntoKeys<K, V, N> {
1343    type Item = K;
1344
1345    #[inline]
1346    fn next(&mut self) -> Option<K> {
1347        self.inner.next().map(|(k, _)| k)
1348    }
1349    #[inline]
1350    fn size_hint(&self) -> (usize, Option<usize>) {
1351        self.inner.size_hint()
1352    }
1353    #[inline]
1354    fn count(self) -> usize {
1355        self.inner.len()
1356    }
1357    #[inline]
1358    fn fold<B, F>(self, init: B, mut f: F) -> B
1359    where
1360        Self: Sized,
1361        F: FnMut(B, Self::Item) -> B,
1362    {
1363        self.inner.fold(init, |acc, (k, _)| f(acc, k))
1364    }
1365}
1366impl<K, V, const N: usize> ExactSizeIterator for IntoKeys<K, V, N> {
1367    #[inline]
1368    fn len(&self) -> usize {
1369        self.inner.len()
1370    }
1371}
1372impl<K, V, const N: usize> FusedIterator for IntoKeys<K, V, N> {}
1373
1374/// An iterator over the values of a `CompactMap`.
1375///
1376/// This `struct` is created by the [`values`] method on [`CompactMap`]. See its
1377/// documentation for more.
1378///
1379/// [`values`]: CompactMap::values
1380///
1381/// # Example
1382///
1383/// ```
1384/// use compact_map::CompactMap;
1385///
1386/// let map: CompactMap<&str, i32, 16> = CompactMap::from([
1387///     ("a", 1),
1388/// ]);
1389/// let iter_values = map.values();
1390/// ```
1391pub struct Values<'a, K: 'a, V: 'a, const N: usize> {
1392    base: base::iter::IterInner<'a, K, V, N>,
1393}
1394
1395impl<'a, K, V, const N: usize> Iterator for Values<'a, K, V, N> {
1396    type Item = &'a V;
1397
1398    #[inline]
1399    fn next(&mut self) -> Option<&'a V> {
1400        self.base.next().map(|(_, v)| v)
1401    }
1402    #[inline]
1403    fn size_hint(&self) -> (usize, Option<usize>) {
1404        self.base.size_hint()
1405    }
1406    #[inline]
1407    fn count(self) -> usize {
1408        self.base.len()
1409    }
1410    #[inline]
1411    fn fold<B, F>(self, init: B, mut f: F) -> B
1412    where
1413        Self: Sized,
1414        F: FnMut(B, Self::Item) -> B,
1415    {
1416        self.base.fold(init, |acc, (_, v)| f(acc, v))
1417    }
1418}
1419impl<K, V, const N: usize> ExactSizeIterator for Values<'_, K, V, N> {
1420    #[inline]
1421    fn len(&self) -> usize {
1422        self.base.len()
1423    }
1424}
1425impl<K, V, const N: usize> FusedIterator for Values<'_, K, V, N> {}
1426
1427/// A mutable iterator over the values of a `CompactMap`.
1428///
1429/// This `struct` is created by the [`values_mut`] method on [`CompactMap`]. See its
1430/// documentation for more.
1431///
1432/// [`values_mut`]: CompactMap::values_mut
1433///
1434/// # Example
1435///
1436/// ```
1437/// use compact_map::CompactMap;
1438///
1439/// let mut map: CompactMap<&str, i32, 16> = CompactMap::from([
1440///     ("a", 1),
1441/// ]);
1442/// let iter_values = map.values_mut();
1443/// ```
1444pub struct ValuesMut<'a, K: 'a, V: 'a, const N: usize> {
1445    inner: base::iter::IterMutInner<'a, K, V, N>,
1446}
1447
1448impl<'a, K, V, const N: usize> Iterator for ValuesMut<'a, K, V, N> {
1449    type Item = &'a mut V;
1450
1451    #[inline]
1452    fn next(&mut self) -> Option<&'a mut V> {
1453        self.inner.next().map(|(_, v)| v)
1454    }
1455    #[inline]
1456    fn size_hint(&self) -> (usize, Option<usize>) {
1457        self.inner.size_hint()
1458    }
1459    #[inline]
1460    fn count(self) -> usize {
1461        self.inner.len()
1462    }
1463    #[inline]
1464    fn fold<B, F>(self, init: B, mut f: F) -> B
1465    where
1466        Self: Sized,
1467        F: FnMut(B, Self::Item) -> B,
1468    {
1469        self.inner.fold(init, |acc, (_, v)| f(acc, v))
1470    }
1471}
1472impl<K, V, const N: usize> ExactSizeIterator for ValuesMut<'_, K, V, N> {
1473    #[inline]
1474    fn len(&self) -> usize {
1475        self.inner.len()
1476    }
1477}
1478impl<K, V, const N: usize> FusedIterator for ValuesMut<'_, K, V, N> {}
1479
1480/// An owning iterator over the values of a `CompactMap`.
1481///
1482/// This `struct` is created by the [`into_values`] method on [`CompactMap`].
1483/// See its documentation for more.
1484///
1485/// [`into_values`]: HashMap::into_values
1486///
1487/// # Example
1488///
1489/// ```
1490/// use compact_map::CompactMap;
1491///
1492/// let map: CompactMap<&str, i32, 16> = CompactMap::from([
1493///     ("a", 1),
1494/// ]);
1495/// let iter_keys = map.into_values();
1496/// ```
1497pub struct IntoValues<K, V, const N: usize> {
1498    inner: base::iter::IntoIterInner<K, V, N>,
1499}
1500
1501impl<K, V, const N: usize> Iterator for IntoValues<K, V, N> {
1502    type Item = V;
1503
1504    #[inline]
1505    fn next(&mut self) -> Option<V> {
1506        self.inner.next().map(|(_, v)| v)
1507    }
1508    #[inline]
1509    fn size_hint(&self) -> (usize, Option<usize>) {
1510        self.inner.size_hint()
1511    }
1512    #[inline]
1513    fn count(self) -> usize {
1514        self.inner.len()
1515    }
1516    #[inline]
1517    fn fold<B, F>(self, init: B, mut f: F) -> B
1518    where
1519        Self: Sized,
1520        F: FnMut(B, Self::Item) -> B,
1521    {
1522        self.inner.fold(init, |acc, (_, v)| f(acc, v))
1523    }
1524}
1525impl<K, V, const N: usize> ExactSizeIterator for IntoValues<K, V, N> {
1526    #[inline]
1527    fn len(&self) -> usize {
1528        self.inner.len()
1529    }
1530}
1531impl<K, V, const N: usize> FusedIterator for IntoValues<K, V, N> {}
1532
1533/// An iterator over the entries of a `CompactMap`.
1534///
1535/// This `struct` is created by the [`iter`] method on [`CompactMap`]. See its
1536/// documentation for more.
1537///
1538/// [`iter`]: CompactMap::iter
1539///
1540/// # Example
1541///
1542/// ```
1543/// use compact_map::CompactMap;
1544///
1545/// let map: CompactMap<&str, i32, 16> = CompactMap::from([
1546///     ("a", 1),
1547/// ]);
1548/// let iter = map.iter();
1549/// ```
1550pub struct Iter<'a, K, V, const N: usize> {
1551    pub(crate) base: base::iter::IterInner<'a, K, V, N>,
1552}
1553
1554impl<'a, K, V, const N: usize> Iterator for Iter<'a, K, V, N> {
1555    type Item = (&'a K, &'a V);
1556
1557    #[inline]
1558    fn next(&mut self) -> Option<(&'a K, &'a V)> {
1559        self.base.next()
1560    }
1561    #[inline]
1562    fn size_hint(&self) -> (usize, Option<usize>) {
1563        self.base.size_hint()
1564    }
1565    #[inline]
1566    fn count(self) -> usize {
1567        self.base.count()
1568    }
1569    #[inline]
1570    fn fold<B, F>(self, init: B, f: F) -> B
1571    where
1572        Self: Sized,
1573        F: FnMut(B, Self::Item) -> B,
1574    {
1575        self.base.fold(init, f)
1576    }
1577}
1578impl<'a, K, V, const N: usize> ExactSizeIterator for Iter<'a, K, V, N> {
1579    #[inline]
1580    fn len(&self) -> usize {
1581        self.base.len()
1582    }
1583}
1584impl<'a, K, V, const N: usize> FusedIterator for Iter<'a, K, V, N> {}
1585
1586/// A mutable iterator over the entries of a `CompactMap`.
1587///
1588/// This `struct` is created by the [`iter_mut`] method on [`CompactMap`]. See its
1589/// documentation for more.
1590///
1591/// [`iter_mut`]: CompactMap::iter_mut
1592///
1593/// # Example
1594///
1595/// ```
1596/// use compact_map::CompactMap;
1597///
1598/// let mut map: CompactMap<&str, i32, 16> = CompactMap::from([
1599///     ("a", 1),
1600/// ]);
1601/// let iter = map.iter_mut();
1602/// ```
1603pub struct IterMut<'a, K: 'a, V: 'a, const N: usize> {
1604    base: base::iter::IterMutInner<'a, K, V, N>,
1605}
1606
1607impl<'a, K, V, const N: usize> Iterator for IterMut<'a, K, V, N> {
1608    type Item = (&'a K, &'a mut V);
1609
1610    #[inline]
1611    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1612        self.base.next()
1613    }
1614    #[inline]
1615    fn size_hint(&self) -> (usize, Option<usize>) {
1616        self.base.size_hint()
1617    }
1618    #[inline]
1619    fn count(self) -> usize {
1620        self.base.len()
1621    }
1622    #[inline]
1623    fn fold<B, F>(self, init: B, f: F) -> B
1624    where
1625        Self: Sized,
1626        F: FnMut(B, Self::Item) -> B,
1627    {
1628        self.base.fold(init, f)
1629    }
1630}
1631impl<K, V, const N: usize> ExactSizeIterator for IterMut<'_, K, V, N> {
1632    #[inline]
1633    fn len(&self) -> usize {
1634        self.base.len()
1635    }
1636}
1637impl<K, V, const N: usize> FusedIterator for IterMut<'_, K, V, N> {}
1638
1639/// An owning iterator over the entries of a `CompactMap`.
1640///
1641/// This `struct` is created by the [`into_iter`] method on [`CompactMap`]
1642/// (provided by the [`IntoIterator`] trait). See its documentation for more.
1643///
1644/// [`into_iter`]: IntoIterator::into_iter
1645///
1646/// # Example
1647///
1648/// ```
1649/// use compact_map::CompactMap;
1650///
1651/// let map: CompactMap<&str, i32, 16> = CompactMap::from([
1652///     ("a", 1),
1653/// ]);
1654/// let iter = map.into_iter();
1655/// ```
1656pub struct IntoIter<K, V, const N: usize> {
1657    base: base::iter::IntoIterInner<K, V, N>,
1658}
1659
1660impl<K: Debug, V: Debug, const N: usize> Debug for IntoIter<K, V, N> {
1661    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1662        self.base.fmt(f)
1663    }
1664}
1665
1666impl<K, V, const N: usize> Iterator for IntoIter<K, V, N> {
1667    type Item = (K, V);
1668
1669    #[inline]
1670    fn next(&mut self) -> Option<(K, V)> {
1671        self.base.next()
1672    }
1673    #[inline]
1674    fn size_hint(&self) -> (usize, Option<usize>) {
1675        self.base.size_hint()
1676    }
1677    #[inline]
1678    fn count(self) -> usize {
1679        self.base.len()
1680    }
1681    #[inline]
1682    fn fold<B, F>(self, init: B, f: F) -> B
1683    where
1684        Self: Sized,
1685        F: FnMut(B, Self::Item) -> B,
1686    {
1687        self.base.fold(init, f)
1688    }
1689}
1690impl<K, V, const N: usize> ExactSizeIterator for IntoIter<K, V, N> {
1691    #[inline]
1692    fn len(&self) -> usize {
1693        self.base.len()
1694    }
1695}
1696impl<K, V, const N: usize> FusedIterator for IntoIter<K, V, N> {}
1697
1698impl<'a, K, V, const N: usize> IntoIterator for &'a CompactMap<K, V, N> {
1699    type Item = (&'a K, &'a V);
1700    type IntoIter = Iter<'a, K, V, N>;
1701
1702    #[inline]
1703    fn into_iter(self) -> Iter<'a, K, V, N> {
1704        self.iter()
1705    }
1706}
1707
1708impl<'a, K, V, const N: usize> IntoIterator for &'a mut CompactMap<K, V, N> {
1709    type Item = (&'a K, &'a mut V);
1710    type IntoIter = IterMut<'a, K, V, N>;
1711
1712    #[inline]
1713    fn into_iter(self) -> IterMut<'a, K, V, N> {
1714        self.iter_mut()
1715    }
1716}
1717
1718/// A draining iterator over the entries of a `CompactMap`.
1719///
1720/// This `struct` is created by the [`drain`] method on [`CompactMap`]. See its
1721/// documentation for more.
1722///
1723/// [`drain`]: CompactMap::drain
1724///
1725/// # Example
1726///
1727/// ```
1728/// use compact_map::CompactMap;
1729///
1730/// let mut map: CompactMap<&str, i32, 16> = CompactMap::from([
1731///     ("a", 1),
1732///     ("b", 2),
1733///     ("c", 3),
1734/// ]);
1735/// let iter = map.drain();
1736/// ```
1737pub struct Drain<'a, K: 'a, V: 'a, const N: usize> {
1738    base: base::drain::DrainInner<'a, K, V, N>,
1739}
1740
1741impl<K: Debug, V: Debug, const N: usize> Debug for Drain<'_, K, V, N> {
1742    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1743        self.base.fmt(f)
1744    }
1745}
1746
1747impl<'a, K, V, const N: usize> Iterator for Drain<'a, K, V, N> {
1748    type Item = (K, V);
1749
1750    #[inline]
1751    fn next(&mut self) -> Option<(K, V)> {
1752        self.base.next()
1753    }
1754    #[inline]
1755    fn size_hint(&self) -> (usize, Option<usize>) {
1756        self.base.size_hint()
1757    }
1758    #[inline]
1759    fn count(self) -> usize {
1760        self.base.count()
1761    }
1762    #[inline]
1763    fn fold<B, F>(self, init: B, f: F) -> B
1764    where
1765        Self: Sized,
1766        F: FnMut(B, Self::Item) -> B,
1767    {
1768        self.base.fold(init, f)
1769    }
1770}
1771impl<K, V, const N: usize> ExactSizeIterator for Drain<'_, K, V, N> {
1772    #[inline]
1773    fn len(&self) -> usize {
1774        self.base.len()
1775    }
1776}
1777impl<K, V, const N: usize> FusedIterator for Drain<'_, K, V, N> {}
1778
1779/// A draining, filtering iterator over the entries of a `CompactMap`.
1780///
1781/// This `struct` is created by the [`extract_if`] method on [`CompactMap`].
1782///
1783/// [`extract_if`]: CompactMap::extract_if
1784///
1785/// # Example
1786///
1787/// ```
1788/// use compact_map::CompactMap;
1789///
1790/// let mut map: CompactMap<&str, i32, 16> = CompactMap::from([
1791///     ("a", 1),
1792///     ("b", 2),
1793///     ("c", 3),
1794/// ]);
1795/// let iter = map.extract_if(|_k, v| *v % 2 == 0);
1796/// ```
1797#[cfg_attr(docsrs, doc(cfg(feature = "extract_if")))]
1798#[cfg(feature = "extract_if")]
1799#[must_use = "iterators are lazy and do nothing unless consumed"]
1800pub struct ExtractIf<'a, K, V, F, const N: usize>
1801where
1802    F: FnMut(&K, &mut V) -> bool,
1803{
1804    base: base::extract_if::ExtractIfInner<'a, K, V, F, N>,
1805}
1806
1807#[cfg_attr(docsrs, doc(cfg(feature = "extract_if")))]
1808#[cfg(feature = "extract_if")]
1809impl<K, V, F, const N: usize> Iterator for ExtractIf<'_, K, V, F, N>
1810where
1811    F: FnMut(&K, &mut V) -> bool,
1812{
1813    type Item = (K, V);
1814
1815    #[inline]
1816    fn next(&mut self) -> Option<(K, V)> {
1817        self.base.next()
1818    }
1819    #[inline]
1820    fn size_hint(&self) -> (usize, Option<usize>) {
1821        self.base.size_hint()
1822    }
1823}
1824
1825#[cfg_attr(docsrs, doc(cfg(feature = "extract_if")))]
1826#[cfg(feature = "extract_if")]
1827impl<K, V, F, const N: usize> FusedIterator for ExtractIf<'_, K, V, F, N> where
1828    F: FnMut(&K, &mut V) -> bool
1829{
1830}
1831
1832#[cfg_attr(docsrs, doc(cfg(feature = "extract_if")))]
1833#[cfg(feature = "extract_if")]
1834impl<'a, K, V, F, const N: usize> Debug for ExtractIf<'a, K, V, F, N>
1835where
1836    F: FnMut(&K, &mut V) -> bool,
1837{
1838    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1839        f.debug_struct("ExtractIf").finish_non_exhaustive()
1840    }
1841}
1842
1843impl<K, V, const N: usize> IntoIterator for CompactMap<K, V, N> {
1844    type Item = (K, V);
1845    type IntoIter = IntoIter<K, V, N>;
1846
1847    /// Creates a consuming iterator, that is, one that moves each key-value
1848    /// pair out of the map in arbitrary order. The map cannot be used after
1849    /// calling this.
1850    ///
1851    /// # Examples
1852    ///
1853    /// ```
1854    /// use compact_map::CompactMap;
1855    ///
1856    /// let map: CompactMap<&str, i32, 16> = CompactMap::from([
1857    ///     ("a", 1),
1858    ///     ("b", 2),
1859    ///     ("c", 3),
1860    /// ]);
1861    ///
1862    /// // Not possible with .iter()
1863    /// let vec: Vec<(&str, i32)> = map.into_iter().collect();
1864    /// ```
1865    #[inline]
1866    fn into_iter(self) -> IntoIter<K, V, N> {
1867        IntoIter {
1868            base: self.base.into_iter(),
1869        }
1870    }
1871}
1872
1873impl<K, V, const N: usize> FromIterator<(K, V)> for CompactMap<K, V, N>
1874where
1875    K: Eq + Hash,
1876{
1877    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
1878        let mut map = CompactMap::new();
1879        map.extend(iter);
1880        map
1881    }
1882}
1883
1884impl<K, V, const N: usize> Extend<(K, V)> for CompactMap<K, V, N>
1885where
1886    K: Eq + Hash,
1887{
1888    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
1889        self.base.extend(iter);
1890    }
1891}