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}