Skip to main content

litemap/
map.rs

1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5use crate::store::*;
6#[cfg(feature = "alloc")]
7use alloc::boxed::Box;
8#[cfg(feature = "alloc")]
9use alloc::vec::Vec;
10use core::borrow::Borrow;
11use core::cmp::Ordering;
12use core::fmt::Debug;
13use core::iter::{FromIterator, FusedIterator};
14use core::marker::PhantomData;
15use core::mem;
16use core::ops::{Index, IndexMut, Range};
17
18macro_rules! litemap_impl(
19    ($cfg:meta, $store:ident $(=$defaultty:ty)?) => {
20        /// A simple "flat" map based on a sorted vector
21        ///
22        /// See the [module level documentation][super] for why one should use this.
23        ///
24        /// The API is roughly similar to that of [`std::collections::BTreeMap`].
25        #[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
26        #[cfg_attr(feature = "yoke", derive(yoke::Yokeable))]
27        #[cfg($cfg)]
28        pub struct LiteMap<K: ?Sized, V: ?Sized, $store $(= $defaultty)?> {
29            pub(crate) values: $store,
30            pub(crate) _key_type: PhantomData<K>,
31            pub(crate) _value_type: PhantomData<V>,
32        }
33    };
34
35);
36// You can't `cfg()` a default generic parameter, and we don't want to write this type twice
37// and keep them in sync so we use a small macro
38litemap_impl!(feature = "alloc", S = Vec<(K, V)>);
39/// A simple "flat" map based on a sorted vector
///
/// See the [module level documentation][super] for why one should use this.
///
/// The API is roughly similar to that of [`std::collections::BTreeMap`].
pub struct LiteMap<K: ?Sized, V: ?Sized, S> {
    pub(crate) values: S,
    pub(crate) _key_type: PhantomData<K>,
    pub(crate) _value_type: PhantomData<V>,
}
#[automatically_derived]
impl<K: ::core::clone::Clone + ?Sized, V: ::core::clone::Clone + ?Sized,
    S: ::core::clone::Clone> ::core::clone::Clone for LiteMap<K, V, S> {
    #[inline]
    fn clone(&self) -> LiteMap<K, V, S> {
        LiteMap {
            values: ::core::clone::Clone::clone(&self.values),
            _key_type: ::core::clone::Clone::clone(&self._key_type),
            _value_type: ::core::clone::Clone::clone(&self._value_type),
        }
    }
}
#[automatically_derived]
impl<K: ::core::fmt::Debug + ?Sized, V: ::core::fmt::Debug + ?Sized,
    S: ::core::fmt::Debug> ::core::fmt::Debug for LiteMap<K, V, S> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "LiteMap",
            "values", &self.values, "_key_type", &self._key_type,
            "_value_type", &&self._value_type)
    }
}
#[automatically_derived]
impl<K: ::core::cmp::PartialEq + ?Sized, V: ::core::cmp::PartialEq + ?Sized,
    S: ::core::cmp::PartialEq> ::core::marker::StructuralPartialEq for
    LiteMap<K, V, S> {
}
#[automatically_derived]
impl<K: ::core::cmp::PartialEq + ?Sized, V: ::core::cmp::PartialEq + ?Sized,
    S: ::core::cmp::PartialEq> ::core::cmp::PartialEq for LiteMap<K, V, S> {
    #[inline]
    fn eq(&self, other: &LiteMap<K, V, S>) -> bool {
        self.values == other.values && self._key_type == other._key_type &&
            self._value_type == other._value_type
    }
}
#[automatically_derived]
impl<K: ::core::cmp::Eq + ?Sized, V: ::core::cmp::Eq + ?Sized,
    S: ::core::cmp::Eq> ::core::cmp::Eq for LiteMap<K, V, S> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<S>;
        let _: ::core::cmp::AssertParamIsEq<PhantomData<K>>;
        let _: ::core::cmp::AssertParamIsEq<PhantomData<V>>;
    }
}
#[automatically_derived]
impl<K: ::core::hash::Hash + ?Sized, V: ::core::hash::Hash + ?Sized,
    S: ::core::hash::Hash> ::core::hash::Hash for LiteMap<K, V, S> {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.values, state);
        ::core::hash::Hash::hash(&self._key_type, state);
        ::core::hash::Hash::hash(&self._value_type, state)
    }
}
#[automatically_derived]
impl<K: ::core::cmp::PartialOrd + ?Sized, V: ::core::cmp::PartialOrd + ?Sized,
    S: ::core::cmp::PartialOrd> ::core::cmp::PartialOrd for LiteMap<K, V, S> {
    #[inline]
    fn partial_cmp(&self, other: &LiteMap<K, V, S>)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.values,
                &other.values) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self._key_type,
                        &other._key_type) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        ::core::cmp::PartialOrd::partial_cmp(&self._value_type,
                            &other._value_type),
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}
#[automatically_derived]
impl<K: ::core::cmp::Ord + ?Sized, V: ::core::cmp::Ord + ?Sized,
    S: ::core::cmp::Ord> ::core::cmp::Ord for LiteMap<K, V, S> {
    #[inline]
    fn cmp(&self, other: &LiteMap<K, V, S>) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.values, &other.values) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self._key_type, &other._key_type)
                    {
                    ::core::cmp::Ordering::Equal =>
                        ::core::cmp::Ord::cmp(&self._value_type,
                            &other._value_type),
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}litemap_impl!(not(feature = "alloc"), S);
40
41#[cfg(feature = "alloc")]
42impl<K, V> LiteMap<K, V> {
43    /// Construct a new [`LiteMap`] backed by Vec  
44    ///
45    /// ✨ *Enabled with the `alloc` Cargo feature.*  
46    pub const fn new_vec() -> Self {
47        Self {
48            values: Vec::new(),
49            _key_type: PhantomData,
50            _value_type: PhantomData,
51        }
52    }
53}
54
55impl<K, V, S> LiteMap<K, V, S> {
56    /// Construct a new [`LiteMap`] using the given values
57    ///
58    /// The store must be sorted and have no duplicate keys.
59    pub const fn from_sorted_store_unchecked(values: S) -> Self {
60        Self {
61            values,
62            _key_type: PhantomData,
63            _value_type: PhantomData,
64        }
65    }
66}
67
68#[cfg(feature = "alloc")]
69impl<K, V> LiteMap<K, V, Vec<(K, V)>> {
70    /// Convert a [`LiteMap`] into a sorted `Vec<(K, V)>`.
71    ///
72    /// ✨ *Enabled with the `alloc` Cargo feature.*
73    #[inline]
74    pub fn into_tuple_vec(self) -> Vec<(K, V)> {
75        self.values
76    }
77}
78
79impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
80where
81    S: StoreConstEmpty<K, V>,
82{
83    /// Create a new empty [`LiteMap`]
84    pub const fn new() -> Self {
85        Self {
86            values: S::EMPTY,
87            _key_type: PhantomData,
88            _value_type: PhantomData,
89        }
90    }
91}
92
93impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
94where
95    S: Store<K, V>,
96{
97    /// The number of elements in the [`LiteMap`]
98    pub fn len(&self) -> usize {
99        self.values.lm_len()
100    }
101
102    /// Whether the [`LiteMap`] is empty
103    pub fn is_empty(&self) -> bool {
104        self.values.lm_is_empty()
105    }
106
107    /// Get the key-value pair residing at a particular index
108    ///
109    /// In most cases, prefer [`LiteMap::get()`] over this method.
110    #[inline]
111    pub fn get_indexed(&self, index: usize) -> Option<(&K, &V)> {
112        self.values.lm_get(index)
113    }
114
115    /// Get the lowest-rank key/value pair from the `LiteMap`, if it exists.
116    ///
117    /// # Examples
118    ///
119    /// ```rust
120    /// use litemap::LiteMap;
121    ///
122    /// let mut map =
123    ///     LiteMap::<i32, &str, Vec<_>>::from_iter([(1, "uno"), (3, "tres")]);
124    ///
125    /// assert_eq!(map.first(), Some((&1, &"uno")));
126    /// ```
127    #[inline]
128    pub fn first(&self) -> Option<(&K, &V)> {
129        self.values.lm_get(0)
130    }
131
132    /// Get the highest-rank key/value pair from the `LiteMap`, if it exists.
133    ///
134    /// # Examples
135    ///
136    /// ```rust
137    /// use litemap::LiteMap;
138    ///
139    /// let mut map =
140    ///     LiteMap::<i32, &str, Vec<_>>::from_iter([(1, "uno"), (3, "tres")]);
141    ///
142    /// assert_eq!(map.last(), Some((&3, &"tres")));
143    /// ```
144    #[inline]
145    pub fn last(&self) -> Option<(&K, &V)> {
146        self.values.lm_last()
147    }
148
149    /// Returns a new [`LiteMap`] with owned keys and values.
150    ///
151    /// The trait bounds allow transforming most slice and string types.
152    ///
153    /// ✨ *Enabled with the `alloc` Cargo feature.*
154    ///
155    /// # Examples
156    ///
157    /// ```
158    /// use litemap::LiteMap;
159    ///
160    /// let mut map: LiteMap<&str, &str> = LiteMap::new_vec();
161    /// map.insert("one", "uno");
162    /// map.insert("two", "dos");
163    ///
164    /// let boxed_map: LiteMap<Box<str>, Box<str>> = map.to_boxed_keys_values();
165    ///
166    /// assert_eq!(boxed_map.get("one"), Some(&Box::from("uno")));
167    /// ```
168    #[cfg(feature = "alloc")]
169    pub fn to_boxed_keys_values<KB: ?Sized, VB: ?Sized, SB>(&self) -> LiteMap<Box<KB>, Box<VB>, SB>
170    where
171        SB: StoreMut<Box<KB>, Box<VB>>,
172        K: Borrow<KB>,
173        V: Borrow<VB>,
174        Box<KB>: for<'a> From<&'a KB>,
175        Box<VB>: for<'a> From<&'a VB>,
176    {
177        let mut values = SB::lm_with_capacity(self.len());
178        for i in 0..self.len() {
179            #[expect(clippy::unwrap_used)] // iterating over our own length
180            let (k, v) = self.values.lm_get(i).unwrap();
181            values.lm_push(Box::from(k.borrow()), Box::from(v.borrow()))
182        }
183        LiteMap {
184            values,
185            _key_type: PhantomData,
186            _value_type: PhantomData,
187        }
188    }
189
190    /// Returns a new [`LiteMap`] with owned keys and cloned values.
191    ///
192    /// The trait bounds allow transforming most slice and string types.
193    ///
194    /// ✨ *Enabled with the `alloc` Cargo feature.*
195    ///
196    /// # Examples
197    ///
198    /// ```
199    /// use litemap::LiteMap;
200    ///
201    /// let mut map: LiteMap<&str, usize> = LiteMap::new_vec();
202    /// map.insert("one", 11);
203    /// map.insert("two", 22);
204    ///
205    /// let boxed_map: LiteMap<Box<str>, usize> = map.to_boxed_keys();
206    ///
207    /// assert_eq!(boxed_map.get("one"), Some(&11));
208    /// ```
209    #[cfg(feature = "alloc")]
210    pub fn to_boxed_keys<KB: ?Sized, SB>(&self) -> LiteMap<Box<KB>, V, SB>
211    where
212        V: Clone,
213        SB: StoreMut<Box<KB>, V>,
214        K: Borrow<KB>,
215        Box<KB>: for<'a> From<&'a KB>,
216    {
217        let mut values = SB::lm_with_capacity(self.len());
218        for i in 0..self.len() {
219            #[expect(clippy::unwrap_used)] // iterating over our own length
220            let (k, v) = self.values.lm_get(i).unwrap();
221            values.lm_push(Box::from(k.borrow()), v.clone())
222        }
223        LiteMap {
224            values,
225            _key_type: PhantomData,
226            _value_type: PhantomData,
227        }
228    }
229
230    /// Returns a new [`LiteMap`] with cloned keys and owned values.
231    ///
232    /// The trait bounds allow transforming most slice and string types.
233    ///
234    /// ✨ *Enabled with the `alloc` Cargo feature.*
235    ///
236    /// # Examples
237    ///
238    /// ```
239    /// use litemap::LiteMap;
240    ///
241    /// let mut map: LiteMap<usize, &str> = LiteMap::new_vec();
242    /// map.insert(11, "uno");
243    /// map.insert(22, "dos");
244    ///
245    /// let boxed_map: LiteMap<usize, Box<str>> = map.to_boxed_values();
246    ///
247    /// assert_eq!(boxed_map.get(&11), Some(&Box::from("uno")));
248    /// ```
249    #[cfg(feature = "alloc")]
250    pub fn to_boxed_values<VB: ?Sized, SB>(&self) -> LiteMap<K, Box<VB>, SB>
251    where
252        K: Clone,
253        SB: StoreMut<K, Box<VB>>,
254        V: Borrow<VB>,
255        Box<VB>: for<'a> From<&'a VB>,
256    {
257        let mut values = SB::lm_with_capacity(self.len());
258        for i in 0..self.len() {
259            #[expect(clippy::unwrap_used)] // iterating over our own length
260            let (k, v) = self.values.lm_get(i).unwrap();
261            values.lm_push(k.clone(), Box::from(v.borrow()))
262        }
263        LiteMap {
264            values,
265            _key_type: PhantomData,
266            _value_type: PhantomData,
267        }
268    }
269}
270
271impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
272where
273    K: Ord,
274    S: Store<K, V>,
275{
276    /// Get the value associated with `key`, if it exists.
277    ///
278    /// ```rust
279    /// use litemap::LiteMap;
280    ///
281    /// let mut map = LiteMap::new_vec();
282    /// map.insert(1, "one");
283    /// map.insert(2, "two");
284    /// assert_eq!(map.get(&1), Some(&"one"));
285    /// assert_eq!(map.get(&3), None);
286    /// ```
287    pub fn get<Q>(&self, key: &Q) -> Option<&V>
288    where
289        K: Borrow<Q>,
290        Q: Ord + ?Sized,
291    {
292        match self.find_index(key) {
293            #[expect(clippy::unwrap_used)] // find_index returns a valid index
294            Ok(found) => Some(self.values.lm_get(found).unwrap().1),
295            Err(_) => None,
296        }
297    }
298
299    /// Binary search the map with `predicate` to find a key, returning the value.
300    pub fn get_by(&self, predicate: impl FnMut(&K) -> Ordering) -> Option<&V> {
301        let index = self.values.lm_binary_search_by(predicate).ok()?;
302        self.values.lm_get(index).map(|(_, v)| v)
303    }
304
305    /// Returns whether `key` is contained in this map
306    ///
307    /// ```rust
308    /// use litemap::LiteMap;
309    ///
310    /// let mut map = LiteMap::new_vec();
311    /// map.insert(1, "one");
312    /// map.insert(2, "two");
313    /// assert!(map.contains_key(&1));
314    /// assert!(!map.contains_key(&3));
315    /// ```
316    pub fn contains_key<Q>(&self, key: &Q) -> bool
317    where
318        K: Borrow<Q>,
319        Q: Ord + ?Sized,
320    {
321        self.find_index(key).is_ok()
322    }
323
324    /// Obtain the index for a given key, or if the key is not found, the index
325    /// at which it would be inserted.
326    ///
327    /// (The return value works equivalently to [`slice::binary_search_by()`])
328    ///
329    /// The indices returned can be used with [`Self::get_indexed()`]. Prefer using
330    /// [`Self::get()`] directly where possible.
331    #[inline]
332    pub fn find_index<Q>(&self, key: &Q) -> Result<usize, usize>
333    where
334        K: Borrow<Q>,
335        Q: Ord + ?Sized,
336    {
337        self.values.lm_binary_search_by(|k| k.borrow().cmp(key))
338    }
339}
340
341impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
342where
343    S: StoreSlice<K, V>,
344{
345    /// Creates a new [`LiteMap`] from a range of the current [`LiteMap`].
346    ///
347    /// # Examples
348    ///
349    /// ```
350    /// use litemap::LiteMap;
351    ///
352    /// let mut map = LiteMap::new_vec();
353    /// map.insert(1, "one");
354    /// map.insert(2, "two");
355    /// map.insert(3, "three");
356    ///
357    /// let mut sub_map = map.get_indexed_range(1..3).expect("valid range");
358    /// assert_eq!(sub_map.get(&1), None);
359    /// assert_eq!(sub_map.get(&2), Some(&"two"));
360    /// assert_eq!(sub_map.get(&3), Some(&"three"));
361    /// ```
362    pub fn get_indexed_range(&self, range: Range<usize>) -> Option<LiteMap<K, V, &S::Slice>> {
363        let subslice = self.values.lm_get_range(range)?;
364        Some(LiteMap {
365            values: subslice,
366            _key_type: PhantomData,
367            _value_type: PhantomData,
368        })
369    }
370
371    /// Borrows this [`LiteMap`] as one of its slice type.
372    ///
373    /// This can be useful in situations where you need a `LiteMap` by value but do not want
374    /// to clone the owned version.
375    ///
376    /// # Examples
377    ///
378    /// ```
379    /// use litemap::LiteMap;
380    ///
381    /// let mut map = LiteMap::new_vec();
382    /// map.insert(1, "one");
383    /// map.insert(2, "two");
384    ///
385    /// let borrowed_map = map.as_sliced();
386    /// assert_eq!(borrowed_map.get(&1), Some(&"one"));
387    /// assert_eq!(borrowed_map.get(&2), Some(&"two"));
388    /// ```
389    pub fn as_sliced(&self) -> LiteMap<K, V, &S::Slice> {
390        // Won't panic: 0..self.len() is within range
391        #[expect(clippy::unwrap_used)]
392        let subslice = self.values.lm_get_range(0..self.len()).unwrap();
393        LiteMap {
394            values: subslice,
395            _key_type: PhantomData,
396            _value_type: PhantomData,
397        }
398    }
399
400    /// Borrows the backing buffer of this [`LiteMap`] as its slice type.
401    ///
402    /// The slice will be sorted.
403    ///
404    /// # Examples
405    ///
406    /// ```
407    /// use litemap::LiteMap;
408    ///
409    /// let mut map = LiteMap::new_vec();
410    /// map.insert(1, "one");
411    /// map.insert(2, "two");
412    ///
413    /// let slice = map.as_slice();
414    /// assert_eq!(slice, &[(1, "one"), (2, "two")]);
415    /// ```
416    pub fn as_slice(&self) -> &S::Slice {
417        // Won't panic: 0..self.len() is within range
418        #[expect(clippy::unwrap_used)]
419        self.values.lm_get_range(0..self.len()).unwrap()
420    }
421}
422
423impl<'a, K: 'a, V: 'a, S> LiteMap<K, V, S>
424where
425    S: Store<K, V>,
426{
427    /// Returns a new [`LiteMap`] with keys and values borrowed from this one.
428    ///
429    /// # Examples
430    ///
431    /// ```
432    /// use litemap::LiteMap;
433    ///
434    /// let mut map: LiteMap<Box<usize>, String> = LiteMap::new_vec();
435    /// map.insert(Box::new(1), "one".to_string());
436    /// map.insert(Box::new(2), "two".to_string());
437    ///
438    /// let borrowed_map: LiteMap<&usize, &str> = map.to_borrowed_keys_values();
439    ///
440    /// assert_eq!(borrowed_map.get(&1), Some(&"one"));
441    /// ```
442    pub fn to_borrowed_keys_values<KB: ?Sized, VB: ?Sized, SB>(
443        &'a self,
444    ) -> LiteMap<&'a KB, &'a VB, SB>
445    where
446        K: Borrow<KB>,
447        V: Borrow<VB>,
448        SB: StoreMut<&'a KB, &'a VB>,
449    {
450        let mut values = SB::lm_with_capacity(self.len());
451        for i in 0..self.len() {
452            #[expect(clippy::unwrap_used)] // iterating over our own length
453            let (k, v) = self.values.lm_get(i).unwrap();
454            values.lm_push(k.borrow(), v.borrow())
455        }
456        LiteMap {
457            values,
458            _key_type: PhantomData,
459            _value_type: PhantomData,
460        }
461    }
462
463    /// Returns a new [`LiteMap`] with keys borrowed from this one and cloned values.
464    ///
465    /// # Examples
466    ///
467    /// ```
468    /// use litemap::LiteMap;
469    ///
470    /// let mut map: LiteMap<Box<usize>, String> = LiteMap::new_vec();
471    /// map.insert(Box::new(1), "one".to_string());
472    /// map.insert(Box::new(2), "two".to_string());
473    ///
474    /// let borrowed_map: LiteMap<&usize, String> = map.to_borrowed_keys();
475    ///
476    /// assert_eq!(borrowed_map.get(&1), Some(&"one".to_string()));
477    /// ```
478    pub fn to_borrowed_keys<KB: ?Sized, SB>(&'a self) -> LiteMap<&'a KB, V, SB>
479    where
480        K: Borrow<KB>,
481        V: Clone,
482        SB: StoreMut<&'a KB, V>,
483    {
484        let mut values = SB::lm_with_capacity(self.len());
485        for i in 0..self.len() {
486            #[expect(clippy::unwrap_used)] // iterating over our own length
487            let (k, v) = self.values.lm_get(i).unwrap();
488            values.lm_push(k.borrow(), v.clone())
489        }
490        LiteMap {
491            values,
492            _key_type: PhantomData,
493            _value_type: PhantomData,
494        }
495    }
496
497    /// Returns a new [`LiteMap`] with values borrowed from this one and cloned keys.
498    ///
499    /// # Examples
500    ///
501    /// ```
502    /// use litemap::LiteMap;
503    ///
504    /// let mut map: LiteMap<Box<usize>, String> = LiteMap::new_vec();
505    /// map.insert(Box::new(1), "one".to_string());
506    /// map.insert(Box::new(2), "two".to_string());
507    ///
508    /// let borrowed_map: LiteMap<Box<usize>, &str> = map.to_borrowed_values();
509    ///
510    /// assert_eq!(borrowed_map.get(&1), Some(&"one"));
511    /// ```
512    pub fn to_borrowed_values<VB: ?Sized, SB>(&'a self) -> LiteMap<K, &'a VB, SB>
513    where
514        K: Clone,
515        V: Borrow<VB>,
516        SB: StoreMut<K, &'a VB>,
517    {
518        let mut values = SB::lm_with_capacity(self.len());
519        for i in 0..self.len() {
520            #[expect(clippy::unwrap_used)] // iterating over our own length
521            let (k, v) = self.values.lm_get(i).unwrap();
522            values.lm_push(k.clone(), v.borrow())
523        }
524        LiteMap {
525            values,
526            _key_type: PhantomData,
527            _value_type: PhantomData,
528        }
529    }
530}
531
532impl<K, V, S> LiteMap<K, V, S>
533where
534    S: StoreMut<K, V>,
535{
536    /// Construct a new [`LiteMap`] with a given capacity
537    pub fn with_capacity(capacity: usize) -> Self {
538        Self {
539            values: S::lm_with_capacity(capacity),
540            _key_type: PhantomData,
541            _value_type: PhantomData,
542        }
543    }
544
545    /// Remove all elements from the [`LiteMap`]
546    pub fn clear(&mut self) {
547        self.values.lm_clear()
548    }
549
550    /// Reserve capacity for `additional` more elements to be inserted into
551    /// the [`LiteMap`] to avoid frequent reallocations.
552    ///
553    /// See [`Vec::reserve()`] for more information.
554    ///
555    /// [`Vec::reserve()`]: alloc::vec::Vec::reserve
556    pub fn reserve(&mut self, additional: usize) {
557        self.values.lm_reserve(additional)
558    }
559}
560
561impl<K, V, S> LiteMap<K, V, S>
562where
563    K: Ord,
564    S: StoreMut<K, V>,
565{
566    /// Get the value associated with `key`, if it exists, as a mutable reference.
567    ///
568    /// ```rust
569    /// use litemap::LiteMap;
570    ///
571    /// let mut map = LiteMap::new_vec();
572    /// map.insert(1, "one");
573    /// map.insert(2, "two");
574    /// if let Some(mut v) = map.get_mut(&1) {
575    ///     *v = "uno";
576    /// }
577    /// assert_eq!(map.get(&1), Some(&"uno"));
578    /// ```
579    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
580    where
581        K: Borrow<Q>,
582        Q: Ord + ?Sized,
583    {
584        match self.find_index(key) {
585            #[expect(clippy::unwrap_used)] // find_index returns a valid index
586            Ok(found) => Some(self.values.lm_get_mut(found).unwrap().1),
587            Err(_) => None,
588        }
589    }
590
591    /// Appends `value` with `key` to the end of the underlying vector, returning
592    /// `key` and `value` _if it failed_. Useful for extending with an existing
593    /// sorted list.
594    /// ```rust
595    /// use litemap::LiteMap;
596    ///
597    /// let mut map = LiteMap::new_vec();
598    /// assert!(map.try_append(1, "uno").is_none());
599    /// assert!(map.try_append(3, "tres").is_none());
600    ///
601    /// assert!(
602    ///     matches!(map.try_append(3, "tres-updated"), Some((3, "tres-updated"))),
603    ///     "append duplicate of last key",
604    /// );
605    ///
606    /// assert!(
607    ///     matches!(map.try_append(2, "dos"), Some((2, "dos"))),
608    ///     "append out of order"
609    /// );
610    ///
611    /// assert_eq!(map.get(&1), Some(&"uno"));
612    ///
613    /// // contains the original value for the key: 3
614    /// assert_eq!(map.get(&3), Some(&"tres"));
615    ///
616    /// // not appended since it wasn't in order
617    /// assert_eq!(map.get(&2), None);
618    /// ```
619    #[must_use]
620    pub fn try_append(&mut self, key: K, value: V) -> Option<(K, V)> {
621        if let Some(last) = self.values.lm_last() {
622            if last.0 >= &key {
623                return Some((key, value));
624            }
625        }
626
627        self.values.lm_push(key, value);
628        None
629    }
630
631    /// Insert `value` with `key`, returning the existing value if it exists.
632    ///
633    /// ```rust
634    /// use litemap::LiteMap;
635    ///
636    /// let mut map = LiteMap::new_vec();
637    /// map.insert(1, "one");
638    /// map.insert(2, "two");
639    /// assert_eq!(map.get(&1), Some(&"one"));
640    /// assert_eq!(map.get(&3), None);
641    /// ```
642    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
643        self.insert_save_key(key, value).map(|(_, v)| v)
644    }
645
646    /// Version of [`Self::insert()`] that returns both the key and the old value.
647    fn insert_save_key(&mut self, key: K, value: V) -> Option<(K, V)> {
648        match self.values.lm_binary_search_by(|k| k.cmp(&key)) {
649            #[expect(clippy::unwrap_used)] // Index came from binary_search
650            Ok(found) => Some((
651                key,
652                mem::replace(self.values.lm_get_mut(found).unwrap().1, value),
653            )),
654            Err(ins) => {
655                self.values.lm_insert(ins, key, value);
656                None
657            }
658        }
659    }
660
661    /// Attempts to insert a unique entry into the map.
662    ///
663    /// If `key` is not already in the map, inserts it with the corresponding `value`
664    /// and returns `None`.
665    ///
666    /// If `key` is already in the map, no change is made to the map, and the key and value
667    /// are returned back to the caller.
668    ///
669    /// ```
670    /// use litemap::LiteMap;
671    ///
672    /// let mut map = LiteMap::new_vec();
673    /// map.insert(1, "one");
674    /// map.insert(3, "three");
675    ///
676    /// // 2 is not yet in the map...
677    /// assert_eq!(map.try_insert(2, "two"), None);
678    /// assert_eq!(map.len(), 3);
679    ///
680    /// // ...but now it is.
681    /// assert_eq!(map.try_insert(2, "TWO"), Some((2, "TWO")));
682    /// assert_eq!(map.len(), 3);
683    /// ```
684    pub fn try_insert(&mut self, key: K, value: V) -> Option<(K, V)> {
685        match self.values.lm_binary_search_by(|k| k.cmp(&key)) {
686            Ok(_) => Some((key, value)),
687            Err(ins) => {
688                self.values.lm_insert(ins, key, value);
689                None
690            }
691        }
692    }
693
694    /// Attempts to insert a unique entry into the map.
695    ///
696    /// If `key` is not already in the map, invokes the closure to compute `value`, inserts
697    /// the pair into the map, and returns a reference to the value. The closure is passed
698    /// a reference to the `key` argument.
699    ///
700    /// If `key` is already in the map, a reference to the existing value is returned.
701    ///
702    /// Additionally, the index of the value in the map is returned. If it is not desirable
703    /// to hold on to the mutable reference's lifetime, the index can be used to access the
704    /// element via [`LiteMap::get_indexed()`].
705    ///
706    /// The closure returns a `Result` to allow for a fallible insertion function. If the
707    /// creation of `value` is infallible, you can use [`core::convert::Infallible`].
708    ///
709    /// ```
710    /// use litemap::LiteMap;
711    ///
712    /// /// Helper function to unwrap an `Infallible` result from the insertion function
713    /// fn unwrap_infallible<T>(result: Result<T, core::convert::Infallible>) -> T {
714    ///     result.unwrap_or_else(|never| match never {})
715    /// }
716    ///
717    /// let mut map = LiteMap::new_vec();
718    /// map.insert(1, "one");
719    /// map.insert(3, "three");
720    ///
721    /// // 2 is not yet in the map...
722    /// let result1 = unwrap_infallible(
723    ///     map.try_get_or_insert(2, |_| Ok("two"))
724    /// );
725    /// assert_eq!(result1.1, &"two");
726    /// assert_eq!(map.len(), 3);
727    ///
728    /// // ...but now it is.
729    /// let result1 = unwrap_infallible(
730    ///     map.try_get_or_insert(2, |_| Ok("TWO"))
731    /// );
732    /// assert_eq!(result1.1, &"two");
733    /// assert_eq!(map.len(), 3);
734    /// ```
735    pub fn try_get_or_insert<E>(
736        &mut self,
737        key: K,
738        value: impl FnOnce(&K) -> Result<V, E>,
739    ) -> Result<(usize, &V), E> {
740        let idx = match self.values.lm_binary_search_by(|k| k.cmp(&key)) {
741            Ok(idx) => idx,
742            Err(idx) => {
743                let value = value(&key)?;
744                self.values.lm_insert(idx, key, value);
745                idx
746            }
747        };
748        #[expect(clippy::unwrap_used)] // item at idx found or inserted above
749        Ok((idx, self.values.lm_get(idx).unwrap().1))
750    }
751
752    /// Remove the value at `key`, returning it if it exists.
753    ///
754    /// ```rust
755    /// use litemap::LiteMap;
756    ///
757    /// let mut map = LiteMap::new_vec();
758    /// map.insert(1, "one");
759    /// map.insert(2, "two");
760    /// assert_eq!(map.remove(&1), Some("one"));
761    /// assert_eq!(map.get(&1), None);
762    /// ```
763    pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
764    where
765        K: Borrow<Q>,
766        Q: Ord + ?Sized,
767    {
768        match self.values.lm_binary_search_by(|k| k.borrow().cmp(key)) {
769            Ok(found) => Some(self.values.lm_remove(found).1),
770            Err(_) => None,
771        }
772    }
773}
774
775impl<K, V, S> LiteMap<K, V, S>
776where
777    K: Ord,
778    S: StoreIntoIterator<K, V> + StoreFromIterator<K, V>,
779{
780    /// Insert all elements from `other` into this `LiteMap`.
781    ///
782    /// If `other` contains keys that already exist in `self`, the values in `other` replace the
783    /// corresponding ones in `self`, and the rejected items from `self` are returned as a new
784    /// `LiteMap`. Otherwise, `None` is returned.
785    ///
786    /// The implementation of this function is optimized if `self` and `other` have no overlap.
787    ///
788    /// # Examples
789    ///
790    /// ```
791    /// use litemap::LiteMap;
792    ///
793    /// let mut map1 = LiteMap::new_vec();
794    /// map1.insert(1, "one");
795    /// map1.insert(2, "two");
796    ///
797    /// let mut map2 = LiteMap::new_vec();
798    /// map2.insert(2, "TWO");
799    /// map2.insert(4, "FOUR");
800    ///
801    /// let leftovers = map1.extend_from_litemap(map2);
802    ///
803    /// assert_eq!(map1.len(), 3);
804    /// assert_eq!(map1.get(&1), Some("one").as_ref());
805    /// assert_eq!(map1.get(&2), Some("TWO").as_ref());
806    /// assert_eq!(map1.get(&4), Some("FOUR").as_ref());
807    ///
808    /// let map3 = leftovers.expect("Duplicate keys");
809    /// assert_eq!(map3.len(), 1);
810    /// assert_eq!(map3.get(&2), Some("two").as_ref());
811    /// ```
812    pub fn extend_from_litemap(&mut self, other: Self) -> Option<Self> {
813        if self.is_empty() {
814            self.values = other.values;
815            return None;
816        }
817        if other.is_empty() {
818            return None;
819        }
820        if self.last().map(|(k, _)| k) < other.first().map(|(k, _)| k) {
821            // append other to self
822            self.values.lm_extend_end(other.values);
823            None
824        } else if self.first().map(|(k, _)| k) > other.last().map(|(k, _)| k) {
825            // prepend other to self
826            self.values.lm_extend_start(other.values);
827            None
828        } else {
829            // insert every element
830            let leftover_tuples = other
831                .values
832                .lm_into_iter()
833                .filter_map(|(k, v)| self.insert_save_key(k, v))
834                .collect();
835            let ret = LiteMap {
836                values: leftover_tuples,
837                _key_type: PhantomData,
838                _value_type: PhantomData,
839            };
840            if ret.is_empty() {
841                None
842            } else {
843                Some(ret)
844            }
845        }
846    }
847}
848
849impl<K, V, S> Default for LiteMap<K, V, S>
850where
851    S: Store<K, V> + Default,
852{
853    fn default() -> Self {
854        Self {
855            values: S::default(),
856            _key_type: PhantomData,
857            _value_type: PhantomData,
858        }
859    }
860}
861impl<K, V, S> Index<&'_ K> for LiteMap<K, V, S>
862where
863    K: Ord,
864    S: Store<K, V>,
865{
866    type Output = V;
867    fn index(&self, key: &K) -> &V {
868        #[expect(clippy::panic)] // documented
869        match self.get(key) {
870            Some(v) => v,
871            None => { ::core::panicking::panic_fmt(format_args!("no entry found for key")); }panic!("no entry found for key"),
872        }
873    }
874}
875impl<K, V, S> IndexMut<&'_ K> for LiteMap<K, V, S>
876where
877    K: Ord,
878    S: StoreMut<K, V>,
879{
880    fn index_mut(&mut self, key: &K) -> &mut V {
881        #[expect(clippy::panic)] // documented
882        match self.get_mut(key) {
883            Some(v) => v,
884            None => { ::core::panicking::panic_fmt(format_args!("no entry found for key")); }panic!("no entry found for key"),
885        }
886    }
887}
888impl<K, V, S> FromIterator<(K, V)> for LiteMap<K, V, S>
889where
890    K: Ord,
891    S: StoreFromIterable<K, V>,
892{
893    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
894        let values = S::lm_sort_from_iter(iter);
895        Self::from_sorted_store_unchecked(values)
896    }
897}
898
899impl<'a, K: 'a, V: 'a, S> LiteMap<K, V, S>
900where
901    S: StoreIterable<'a, K, V>,
902{
903    /// Produce an ordered iterator over key-value pairs
904    pub fn iter(&'a self) -> S::KeyValueIter {
905        self.values.lm_iter()
906    }
907
908    /// Produce an ordered iterator over keys
909    #[deprecated = "use keys() instead"]
910    pub fn iter_keys(&'a self) -> impl DoubleEndedIterator<Item = &'a K> {
911        self.values.lm_iter().map(|val| val.0)
912    }
913
914    /// Produce an iterator over values, ordered by their keys
915    #[deprecated = "use values() instead"]
916    pub fn iter_values(&'a self) -> impl DoubleEndedIterator<Item = &'a V> {
917        self.values.lm_iter().map(|val| val.1)
918    }
919
920    /// Produce an ordered iterator over keys
921    pub fn keys(&'a self) -> KeysIterWrap<S::KeyValueIter> {
922        KeysIterWrap {
923            iter: self.values.lm_iter(),
924        }
925    }
926
927    /// Produce an iterator over values, ordered by their keys
928    pub fn values(&'a self) -> ValuesIterWrap<S::KeyValueIter> {
929        ValuesIterWrap {
930            iter: self.values.lm_iter(),
931        }
932    }
933}
934
935impl<'a, K: 'a, V: 'a, S> LiteMap<K, V, S>
936where
937    S: StoreIterableMut<'a, K, V>,
938{
939    /// Produce an ordered mutable iterator over key-value pairs
940    pub fn iter_mut(&'a mut self) -> S::KeyValueIterMut {
941        self.values.lm_iter_mut()
942    }
943}
944
945impl<K, V, S> IntoIterator for LiteMap<K, V, S>
946where
947    S: StoreIntoIterator<K, V>,
948{
949    type Item = (K, V);
950    type IntoIter = S::KeyValueIntoIter;
951
952    fn into_iter(self) -> Self::IntoIter {
953        self.values.lm_into_iter()
954    }
955}
956
957impl<'a, K, V, S> IntoIterator for &'a LiteMap<K, V, S>
958where
959    S: StoreIterable<'a, K, V>,
960{
961    type Item = (&'a K, &'a V);
962    type IntoIter = S::KeyValueIter;
963
964    fn into_iter(self) -> Self::IntoIter {
965        self.values.lm_iter()
966    }
967}
968
969impl<'a, K, V, S> IntoIterator for &'a mut LiteMap<K, V, S>
970where
971    S: StoreIterableMut<'a, K, V>,
972{
973    type Item = (&'a K, &'a mut V);
974    type IntoIter = S::KeyValueIterMut;
975
976    fn into_iter(self) -> Self::IntoIter {
977        self.values.lm_iter_mut()
978    }
979}
980
981impl<K, V, S> LiteMap<K, V, S>
982where
983    S: StoreBulkMut<K, V>,
984{
985    /// Retains only the elements specified by the predicate.
986    ///
987    /// In other words, remove all elements such that `f((&k, &v))` returns `false`.
988    ///
989    /// # Example
990    ///
991    /// ```rust
992    /// use litemap::LiteMap;
993    ///
994    /// let mut map = LiteMap::new_vec();
995    /// map.insert(1, "one");
996    /// map.insert(2, "two");
997    /// map.insert(3, "three");
998    ///
999    /// // Retain elements with odd keys
1000    /// map.retain(|k, _| k % 2 == 1);
1001    ///
1002    /// assert_eq!(map.get(&1), Some(&"one"));
1003    /// assert_eq!(map.get(&2), None);
1004    /// ```
1005    #[inline]
1006    pub fn retain<F>(&mut self, predicate: F)
1007    where
1008        F: FnMut(&K, &V) -> bool,
1009    {
1010        self.values.lm_retain(predicate)
1011    }
1012}
1013
1014impl<'a, K, V> LiteMap<K, V, &'a [(K, V)]> {
1015    /// Const version of [`LiteMap::len()`] for a slice store.
1016    ///
1017    /// Note: This function will no longer be needed if const trait behavior is stabilized.
1018    ///
1019    /// # Examples
1020    ///
1021    /// ```rust
1022    /// use litemap::LiteMap;
1023    ///
1024    /// const MAP: LiteMap<&str, usize, &[(&str, usize)]> =
1025    ///     LiteMap::from_sorted_store_unchecked(&[("a", 11), ("b", 22)]);
1026    /// assert_eq!(const { MAP.const_len() }, 2);
1027    /// ```
1028    #[inline]
1029    pub const fn const_len(&self) -> usize {
1030        self.values.len()
1031    }
1032
1033    /// Const version of [`LiteMap::is_empty()`] for a slice store.
1034    ///
1035    /// Note: This function will no longer be needed if const trait behavior is stabilized.
1036    ///
1037    /// # Examples
1038    ///
1039    /// ```rust
1040    /// use litemap::LiteMap;
1041    ///
1042    /// const MAP: LiteMap<&str, usize, &[(&str, usize)]> =
1043    ///     LiteMap::from_sorted_store_unchecked(&[]);
1044    /// assert!(const { MAP.const_is_empty() });
1045    /// ```
1046    #[inline]
1047    pub const fn const_is_empty(&self) -> bool {
1048        self.values.is_empty()
1049    }
1050
1051    /// Const version of [`LiteMap::get_indexed()`] for a slice store.
1052    ///
1053    /// Note: This function will no longer be needed if const trait behavior is stabilized.
1054    ///
1055    /// # Panics
1056    ///
1057    /// Panics if the index is out of bounds.
1058    ///
1059    /// # Examples
1060    ///
1061    /// ```rust
1062    /// use litemap::LiteMap;
1063    ///
1064    /// const MAP: LiteMap<&str, usize, &[(&str, usize)]> =
1065    ///     LiteMap::from_sorted_store_unchecked(&[("a", 11), ("b", 22)]);
1066    /// assert_eq!(const { *MAP.const_get_indexed_or_panic(0) }, ("a", 11));
1067    /// ```
1068    #[inline]
1069    #[expect(clippy::indexing_slicing)] // documented
1070    pub const fn const_get_indexed_or_panic(&self, index: usize) -> &'a (K, V) {
1071        &self.values[index]
1072    }
1073}
1074
1075const fn const_cmp_bytes(a: &[u8], b: &[u8]) -> Ordering {
1076    let (max, default) = if a.len() == b.len() {
1077        (a.len(), Ordering::Equal)
1078    } else if a.len() < b.len() {
1079        (a.len(), Ordering::Less)
1080    } else {
1081        (b.len(), Ordering::Greater)
1082    };
1083    let mut i = 0;
1084    #[expect(clippy::indexing_slicing)] // indexes in range by above checks
1085    while i < max {
1086        if a[i] == b[i] {
1087            i += 1;
1088            continue;
1089        } else if a[i] < b[i] {
1090            return Ordering::Less;
1091        } else {
1092            return Ordering::Greater;
1093        }
1094    }
1095    default
1096}
1097
1098impl<'a, V> LiteMap<&'a str, V, &'a [(&'a str, V)]> {
1099    /// Const function to get the value associated with a `&str` key, if it exists.
1100    ///
1101    /// Also returns the index of the value.
1102    ///
1103    /// Note: This function will no longer be needed if const trait behavior is stabilized.
1104    ///
1105    /// # Examples
1106    ///
1107    /// ```rust
1108    /// use litemap::LiteMap;
1109    ///
1110    /// const MAP: LiteMap<&str, usize, &[(&str, usize)]> =
1111    ///     LiteMap::from_sorted_store_unchecked(&[
1112    ///         ("abc", 11),
1113    ///         ("bcd", 22),
1114    ///         ("cde", 33),
1115    ///         ("def", 44),
1116    ///         ("efg", 55),
1117    ///     ]);
1118    ///
1119    /// assert_eq!(const { MAP.const_get_with_index("def") }, Some((3, &44)));
1120    ///
1121    /// assert_eq!(const { MAP.const_get_with_index("dng") }, None);
1122    /// ```
1123    pub const fn const_get_with_index(&self, key: &str) -> Option<(usize, &'a V)> {
1124        let mut i = 0;
1125        let mut j = self.const_len();
1126        while i < j {
1127            let mid = (i + j) / 2;
1128            #[expect(clippy::indexing_slicing)] // in range
1129            let x = &self.values[mid];
1130            match const_cmp_bytes(key.as_bytes(), x.0.as_bytes()) {
1131                Ordering::Equal => return Some((mid, &x.1)),
1132                Ordering::Greater => i = mid + 1,
1133                Ordering::Less => j = mid,
1134            };
1135        }
1136        None
1137    }
1138}
1139
1140impl<'a, V> LiteMap<&'a [u8], V, &'a [(&'a [u8], V)]> {
1141    /// Const function to get the value associated with a `&[u8]` key, if it exists.
1142    ///
1143    /// Also returns the index of the value.
1144    ///
1145    /// Note: This function will no longer be needed if const trait behavior is stabilized.
1146    ///
1147    /// # Examples
1148    ///
1149    /// ```rust
1150    /// use litemap::LiteMap;
1151    ///
1152    /// const MAP: LiteMap<&[u8], usize, &[(&[u8], usize)]> =
1153    ///     LiteMap::from_sorted_store_unchecked(&[
1154    ///         (b"abc", 11),
1155    ///         (b"bcd", 22),
1156    ///         (b"cde", 33),
1157    ///         (b"def", 44),
1158    ///         (b"efg", 55),
1159    ///     ]);
1160    ///
1161    /// assert_eq!(const { MAP.const_get_with_index(b"def") }, Some((3, &44)));
1162    ///
1163    /// assert_eq!(const { MAP.const_get_with_index(b"dng") }, None);
1164    /// ```
1165    pub const fn const_get_with_index(&self, key: &[u8]) -> Option<(usize, &'a V)> {
1166        let mut i = 0;
1167        let mut j = self.const_len();
1168        while i < j {
1169            let mid = (i + j) / 2;
1170            #[expect(clippy::indexing_slicing)] // in range
1171            let x = &self.values[mid];
1172            match const_cmp_bytes(key, x.0) {
1173                Ordering::Equal => return Some((mid, &x.1)),
1174                Ordering::Greater => i = mid + 1,
1175                Ordering::Less => j = mid,
1176            };
1177        }
1178        None
1179    }
1180}
1181
1182macro_rules! impl_const_get_with_index_for_integer {
1183    ($integer:ty) => {
1184        impl<'a, V> LiteMap<$integer, V, &'a [($integer, V)]> {
1185            /// Const function to get the value associated with an integer key, if it exists.
1186            ///
1187            /// Note: This function will no longer be needed if const trait behavior is stabilized.
1188            ///
1189            /// Also returns the index of the value.
1190            pub const fn const_get_with_index(&self, key: $integer) -> Option<(usize, &'a V)> {
1191                let mut i = 0;
1192                let mut j = self.const_len();
1193                while i < j {
1194                    let mid = (i + j) / 2;
1195                    #[expect(clippy::indexing_slicing)] // in range
1196                    let x = &self.values[mid];
1197                    if key == x.0 {
1198                        return Some((mid, &x.1));
1199                    } else if key > x.0 {
1200                        i = mid + 1;
1201                    } else {
1202                        j = mid;
1203                    }
1204                }
1205                return None;
1206            }
1207        }
1208    };
1209}
1210
1211impl<'a, V> LiteMap<u8, V, &'a [(u8, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: u8)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(u8);
1212impl<'a, V> LiteMap<u16, V, &'a [(u16, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: u16)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(u16);
1213impl<'a, V> LiteMap<u32, V, &'a [(u32, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: u32)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(u32);
1214impl<'a, V> LiteMap<u64, V, &'a [(u64, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: u64)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(u64);
1215impl<'a, V> LiteMap<u128, V, &'a [(u128, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: u128)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(u128);
1216impl<'a, V> LiteMap<usize, V, &'a [(usize, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: usize)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(usize);
1217impl<'a, V> LiteMap<i8, V, &'a [(i8, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: i8)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(i8);
1218impl<'a, V> LiteMap<i16, V, &'a [(i16, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: i16)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(i16);
1219impl<'a, V> LiteMap<i32, V, &'a [(i32, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: i32)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(i32);
1220impl<'a, V> LiteMap<i64, V, &'a [(i64, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: i64)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(i64);
1221impl<'a, V> LiteMap<i128, V, &'a [(i128, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: i128)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(i128);
1222impl<'a, V> LiteMap<isize, V, &'a [(isize, V)]> {
    /// Const function to get the value associated with an integer key, if it exists.
    ///
    /// Note: This function will no longer be needed if const trait behavior is stabilized.
    ///
    /// Also returns the index of the value.
    pub const fn const_get_with_index(&self, key: isize)
        -> Option<(usize, &'a V)> {
        let mut i = 0;
        let mut j = self.const_len();
        while i < j {
            let mid = (i + j) / 2;
            #[expect(clippy :: indexing_slicing)]
            let x = &self.values[mid];
            if key == x.0 {
                return Some((mid, &x.1));
            } else if key > x.0 { i = mid + 1; } else { j = mid; }
        }
        return None;
    }
}impl_const_get_with_index_for_integer!(isize);
1223
1224/// An [`Iterator`] adapter over the keys of a [`StoreIterable::KeyValueIter`].
1225///
1226/// This `struct` is created by the [`LiteMap::keys`] method See its documentation for more.
1227#[derive(#[automatically_derived]
impl<I: ::core::fmt::Debug> ::core::fmt::Debug for KeysIterWrap<I> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "KeysIterWrap",
            "iter", &&self.iter)
    }
}Debug, #[automatically_derived]
impl<I: ::core::clone::Clone> ::core::clone::Clone for KeysIterWrap<I> {
    #[inline]
    fn clone(&self) -> KeysIterWrap<I> {
        KeysIterWrap { iter: ::core::clone::Clone::clone(&self.iter) }
    }
}Clone)]
1228pub struct KeysIterWrap<I> {
1229    iter: I,
1230}
1231
1232/// An [`Iterator`] adapter over the values of a [`StoreIterable::KeyValueIter`].
1233///
1234/// This `struct` is created by the [`LiteMap::values`] method. See its documentation for more.
1235#[derive(#[automatically_derived]
impl<I: ::core::fmt::Debug> ::core::fmt::Debug for ValuesIterWrap<I> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "ValuesIterWrap", "iter", &&self.iter)
    }
}Debug, #[automatically_derived]
impl<I: ::core::clone::Clone> ::core::clone::Clone for ValuesIterWrap<I> {
    #[inline]
    fn clone(&self) -> ValuesIterWrap<I> {
        ValuesIterWrap { iter: ::core::clone::Clone::clone(&self.iter) }
    }
}Clone)]
1236pub struct ValuesIterWrap<I> {
1237    iter: I,
1238}
1239
1240impl<K, V, I: Iterator<Item = (K, V)>> Iterator for KeysIterWrap<I> {
1241    type Item = K;
1242
1243    #[inline]
1244    fn size_hint(&self) -> (usize, Option<usize>) {
1245        self.iter.size_hint()
1246    }
1247    #[inline]
1248    fn next(&mut self) -> Option<Self::Item> {
1249        self.iter.next().map(|val| val.0)
1250    }
1251    #[inline]
1252    fn fold<B, F>(self, init: B, f: F) -> B
1253    where
1254        Self: Sized,
1255        F: FnMut(B, Self::Item) -> B,
1256    {
1257        self.iter.map(|val| val.0).fold(init, f)
1258    }
1259    #[inline]
1260    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1261        self.iter.nth(n).map(|val| val.0)
1262    }
1263}
1264impl<K, V, I: ExactSizeIterator<Item = (K, V)>> ExactSizeIterator for KeysIterWrap<I> {}
1265impl<K, V, I: FusedIterator<Item = (K, V)>> FusedIterator for KeysIterWrap<I> {}
1266impl<K, V, I: DoubleEndedIterator<Item = (K, V)>> DoubleEndedIterator for KeysIterWrap<I> {
1267    #[inline]
1268    fn next_back(&mut self) -> Option<Self::Item> {
1269        self.iter.next_back().map(|val| val.0)
1270    }
1271}
1272
1273impl<K, V, I: Iterator<Item = (K, V)>> Iterator for ValuesIterWrap<I> {
1274    type Item = V;
1275
1276    #[inline]
1277    fn size_hint(&self) -> (usize, Option<usize>) {
1278        self.iter.size_hint()
1279    }
1280    #[inline]
1281    fn next(&mut self) -> Option<Self::Item> {
1282        self.iter.next().map(|val| val.1)
1283    }
1284    #[inline]
1285    fn fold<B, F>(self, init: B, f: F) -> B
1286    where
1287        Self: Sized,
1288        F: FnMut(B, Self::Item) -> B,
1289    {
1290        self.iter.map(|val| val.1).fold(init, f)
1291    }
1292    #[inline]
1293    fn nth(&mut self, n: usize) -> Option<Self::Item> {
1294        self.iter.nth(n).map(|val| val.1)
1295    }
1296}
1297impl<K, V, I: ExactSizeIterator<Item = (K, V)>> ExactSizeIterator for ValuesIterWrap<I> {}
1298impl<K, V, I: FusedIterator<Item = (K, V)>> FusedIterator for ValuesIterWrap<I> {}
1299impl<K, V, I: DoubleEndedIterator<Item = (K, V)>> DoubleEndedIterator for ValuesIterWrap<I> {
1300    #[inline]
1301    fn next_back(&mut self) -> Option<Self::Item> {
1302        self.iter.next_back().map(|val| val.1)
1303    }
1304}
1305
1306/// An entry in a `LiteMap`, which may be either occupied or vacant.
1307#[allow(clippy::exhaustive_enums)]
1308pub enum Entry<'a, K, V, S> {
1309    Occupied(OccupiedEntry<'a, K, V, S>),
1310    Vacant(VacantEntry<'a, K, V, S>),
1311}
1312
1313impl<K, V, S> Debug for Entry<'_, K, V, S> {
1314    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1315        match self {
1316            Self::Occupied(arg0) => f.debug_tuple("Occupied").field(arg0).finish(),
1317            Self::Vacant(arg0) => f.debug_tuple("Vacant").field(arg0).finish(),
1318        }
1319    }
1320}
1321
1322/// A view into an occupied entry in a `LiteMap`.
1323pub struct OccupiedEntry<'a, K, V, S> {
1324    map: &'a mut LiteMap<K, V, S>,
1325    index: usize,
1326}
1327
1328impl<K, V, S> Debug for OccupiedEntry<'_, K, V, S> {
1329    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1330        f.debug_struct("OccupiedEntry")
1331            .field("index", &self.index)
1332            .finish()
1333    }
1334}
1335
1336/// A view into a vacant entry in a `LiteMap`.
1337pub struct VacantEntry<'a, K, V, S> {
1338    map: &'a mut LiteMap<K, V, S>,
1339    key: K,
1340    index: usize,
1341}
1342
1343impl<K, V, S> Debug for VacantEntry<'_, K, V, S> {
1344    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1345        f.debug_struct("VacantEntry")
1346            .field("index", &self.index)
1347            .finish()
1348    }
1349}
1350
1351impl<'a, K, V, S> Entry<'a, K, V, S>
1352where
1353    K: Ord,
1354    S: StoreMut<K, V>,
1355{
1356    /// Ensures a value is in the entry by inserting the default value if empty,
1357    /// and returns a mutable reference to the value in the entry.
1358    pub fn or_insert(self, default: V) -> &'a mut V {
1359        match self {
1360            Entry::Occupied(entry) => entry.into_mut(),
1361            Entry::Vacant(entry) => entry.insert(default),
1362        }
1363    }
1364
1365    /// Ensures a value is in the entry by inserting the result of the default function if empty,
1366    /// and returns a mutable reference to the value in the entry.
1367    pub fn or_default(self) -> &'a mut V
1368    where
1369        V: Default,
1370    {
1371        self.or_insert(V::default())
1372    }
1373
1374    /// Ensures a value is in the entry by inserting the result of the default function if empty,
1375    /// and returns a mutable reference to the value in the entry.
1376    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
1377        match self {
1378            Entry::Occupied(entry) => entry.into_mut(),
1379            Entry::Vacant(entry) => entry.insert(default()),
1380        }
1381    }
1382
1383    /// Provides in-place mutable access to an occupied entry before any
1384    /// potential inserts into the map.
1385    pub fn and_modify<F>(self, f: F) -> Self
1386    where
1387        F: FnOnce(&mut V),
1388    {
1389        match self {
1390            Entry::Occupied(mut entry) => {
1391                f(entry.get_mut());
1392                Entry::Occupied(entry)
1393            }
1394            Entry::Vacant(entry) => Entry::Vacant(entry),
1395        }
1396    }
1397}
1398
1399impl<'a, K, V, S> OccupiedEntry<'a, K, V, S>
1400where
1401    K: Ord,
1402    S: StoreMut<K, V>,
1403{
1404    /// Gets a reference to the key in the entry.
1405    pub fn key(&self) -> &K {
1406        #[expect(clippy::unwrap_used)] // index is valid while we have a reference to the map
1407        self.map.values.lm_get(self.index).unwrap().0
1408    }
1409
1410    /// Gets a reference to the value in the entry.
1411    pub fn get(&self) -> &V {
1412        #[expect(clippy::unwrap_used)] // index is valid while we have a reference to the map
1413        self.map.values.lm_get(self.index).unwrap().1
1414    }
1415
1416    /// Gets a mutable reference to the value in the entry.
1417    pub fn get_mut(&mut self) -> &mut V {
1418        #[expect(clippy::unwrap_used)] // index is valid while we have a reference to the map
1419        self.map.values.lm_get_mut(self.index).unwrap().1
1420    }
1421
1422    /// Converts the entry into a mutable reference to the value in the entry with a lifetime bound to the map.
1423    pub fn into_mut(self) -> &'a mut V {
1424        #[expect(clippy::unwrap_used)] // index is valid while we have a reference to the map
1425        self.map.values.lm_get_mut(self.index).unwrap().1
1426    }
1427
1428    /// Sets the value of the entry, and returns the entry's old value.
1429    pub fn insert(&mut self, value: V) -> V {
1430        mem::replace(self.get_mut(), value)
1431    }
1432
1433    /// Takes the value out of the entry, and returns it.
1434    pub fn remove(self) -> V {
1435        self.map.values.lm_remove(self.index).1
1436    }
1437}
1438
1439impl<'a, K, V, S> VacantEntry<'a, K, V, S>
1440where
1441    K: Ord,
1442    S: StoreMut<K, V>,
1443{
1444    /// Gets a reference to the key that would be used when inserting a value through the `VacantEntry`.
1445    pub fn key(&self) -> &K {
1446        &self.key
1447    }
1448
1449    /// Sets the value of the entry with the `VacantEntry`'s key, and returns a mutable reference to it.
1450    pub fn insert(self, value: V) -> &'a mut V {
1451        // index is valid insert index that was found via binary search
1452        // it's valid while we have a reference to the map
1453        self.map.values.lm_insert(self.index, self.key, value);
1454        #[expect(clippy::unwrap_used)] // we inserted at self.index above
1455        self.map.values.lm_get_mut(self.index).unwrap().1
1456    }
1457}
1458
1459impl<K, V, S> LiteMap<K, V, S>
1460where
1461    K: Ord,
1462    S: StoreMut<K, V>,
1463{
1464    /// Gets the entry for the given key in the map for in-place manipulation.
1465    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S> {
1466        match self.values.lm_binary_search_by(|k| k.cmp(&key)) {
1467            Ok(index) => Entry::Occupied(OccupiedEntry { map: self, index }),
1468            Err(index) => Entry::Vacant(VacantEntry {
1469                map: self,
1470                key,
1471                index,
1472            }),
1473        }
1474    }
1475}
1476
1477impl<K, V, S> Extend<(K, V)> for LiteMap<K, V, S>
1478where
1479    K: Ord,
1480    S: StoreBulkMut<K, V>,
1481{
1482    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
1483        self.values.lm_extend(iter)
1484    }
1485}
1486
1487#[cfg(test)]
1488mod test {
1489    use super::*;
1490
1491    #[test]
1492    fn from_iterator() {
1493        let mut expected = LiteMap::with_capacity(4);
1494        expected.insert(1, "updated-one");
1495        expected.insert(2, "original-two");
1496        expected.insert(3, "original-three");
1497        expected.insert(4, "updated-four");
1498
1499        let actual = [
1500            (1, "original-one"),
1501            (2, "original-two"),
1502            (4, "original-four"),
1503            (4, "updated-four"),
1504            (1, "updated-one"),
1505            (3, "original-three"),
1506        ]
1507        .into_iter()
1508        .collect::<LiteMap<_, _>>();
1509
1510        assert_eq!(expected, actual);
1511    }
1512
1513    #[test]
1514    fn extend() {
1515        let mut expected: LiteMap<i32, &str> = LiteMap::with_capacity(4);
1516        expected.insert(1, "updated-one");
1517        expected.insert(2, "original-two");
1518        expected.insert(3, "original-three");
1519        expected.insert(4, "updated-four");
1520
1521        let mut actual: LiteMap<i32, &str> = LiteMap::new();
1522        actual.insert(1, "original-one");
1523        actual.extend([
1524            (2, "original-two"),
1525            (4, "original-four"),
1526            (4, "updated-four"),
1527            (1, "updated-one"),
1528            (3, "original-three"),
1529        ]);
1530
1531        assert_eq!(expected, actual);
1532    }
1533
1534    #[test]
1535    fn extend2() {
1536        let mut map: LiteMap<usize, &str> = LiteMap::new();
1537        map.extend(make_13());
1538        map.extend(make_24());
1539        map.extend(make_24());
1540        map.extend(make_46());
1541        map.extend(make_13());
1542        map.extend(make_46());
1543        assert_eq!(map.len(), 5);
1544    }
1545
1546    fn make_13() -> LiteMap<usize, &'static str> {
1547        let mut result = LiteMap::new();
1548        result.insert(1, "one");
1549        result.insert(3, "three");
1550        result
1551    }
1552
1553    fn make_24() -> LiteMap<usize, &'static str> {
1554        let mut result = LiteMap::new();
1555        result.insert(2, "TWO");
1556        result.insert(4, "FOUR");
1557        result
1558    }
1559
1560    fn make_46() -> LiteMap<usize, &'static str> {
1561        let mut result = LiteMap::new();
1562        result.insert(4, "four");
1563        result.insert(6, "six");
1564        result
1565    }
1566
1567    #[test]
1568    fn extend_from_litemap_append() {
1569        let mut map = LiteMap::new();
1570        map.extend_from_litemap(make_13())
1571            .ok_or(())
1572            .expect_err("Append to empty map");
1573        map.extend_from_litemap(make_46())
1574            .ok_or(())
1575            .expect_err("Append to lesser map");
1576        assert_eq!(map.len(), 4);
1577    }
1578
1579    #[test]
1580    fn extend_from_litemap_prepend() {
1581        let mut map = LiteMap::new();
1582        map.extend_from_litemap(make_46())
1583            .ok_or(())
1584            .expect_err("Prepend to empty map");
1585        map.extend_from_litemap(make_13())
1586            .ok_or(())
1587            .expect_err("Prepend to lesser map");
1588        assert_eq!(map.len(), 4);
1589    }
1590
1591    #[test]
1592    fn extend_from_litemap_insert() {
1593        let mut map = LiteMap::new();
1594        map.extend_from_litemap(make_13())
1595            .ok_or(())
1596            .expect_err("Append to empty map");
1597        map.extend_from_litemap(make_24())
1598            .ok_or(())
1599            .expect_err("Insert with no conflict");
1600        map.extend_from_litemap(make_46())
1601            .ok_or(())
1602            .expect("Insert with conflict");
1603        assert_eq!(map.len(), 5);
1604    }
1605
1606    #[test]
1607    fn test_const_cmp_bytes() {
1608        let strs = &["a", "aa", "abc", "abde", "bcd", "bcde"];
1609        for i in 0..strs.len() {
1610            for j in 0..strs.len() {
1611                let a = strs[i].as_bytes();
1612                let b = strs[j].as_bytes();
1613                assert_eq!(a.cmp(b), const_cmp_bytes(a, b));
1614            }
1615        }
1616    }
1617
1618    #[test]
1619    fn into_iterator() {
1620        let mut map = LiteMap::<_, _, Vec<(_, _)>>::new();
1621        map.insert(4, "four");
1622        map.insert(6, "six");
1623        let mut reference = vec![(6, "six"), (4, "four")];
1624
1625        for i in map {
1626            let r = reference.pop().unwrap();
1627            assert_eq!(r, i);
1628        }
1629        assert!(reference.is_empty());
1630    }
1631
1632    #[test]
1633    fn entry_insert() {
1634        let mut map: LiteMap<i32, &str> = LiteMap::new();
1635        assert!(matches!(map.entry(1), Entry::Vacant(_)));
1636        map.entry(1).or_insert("one");
1637        assert!(matches!(map.entry(1), Entry::Occupied(_)));
1638        assert_eq!(map.get(&1), Some(&"one"));
1639    }
1640
1641    #[test]
1642    fn entry_insert_with() {
1643        let mut map: LiteMap<i32, &str> = LiteMap::new();
1644        assert!(matches!(map.entry(1), Entry::Vacant(_)));
1645        map.entry(1).or_insert_with(|| "one");
1646        assert!(matches!(map.entry(1), Entry::Occupied(_)));
1647        assert_eq!(map.get(&1), Some(&"one"));
1648    }
1649
1650    #[test]
1651    fn entry_vacant_insert() {
1652        let mut map: LiteMap<i32, &str> = LiteMap::new();
1653        if let Entry::Vacant(entry) = map.entry(1) {
1654            entry.insert("one");
1655        }
1656        assert_eq!(map.get(&1), Some(&"one"));
1657    }
1658
1659    #[test]
1660    fn entry_occupied_get_mut() {
1661        let mut map: LiteMap<i32, &str> = LiteMap::new();
1662        map.insert(1, "one");
1663        if let Entry::Occupied(mut entry) = map.entry(1) {
1664            *entry.get_mut() = "uno";
1665        }
1666        assert_eq!(map.get(&1), Some(&"uno"));
1667    }
1668
1669    #[test]
1670    fn entry_occupied_remove() {
1671        let mut map: LiteMap<i32, &str> = LiteMap::new();
1672        map.insert(1, "one");
1673        if let Entry::Occupied(entry) = map.entry(1) {
1674            entry.remove();
1675        }
1676        assert_eq!(map.get(&1), None);
1677    }
1678
1679    #[test]
1680    fn entry_occupied_key() {
1681        let mut map: LiteMap<i32, &str> = LiteMap::new();
1682        map.insert(1, "one");
1683        if let Entry::Occupied(entry) = map.entry(1) {
1684            assert_eq!(entry.key(), &1);
1685        }
1686    }
1687
1688    #[test]
1689    fn entry_occupied_get() {
1690        let mut map: LiteMap<i32, &str> = LiteMap::new();
1691        map.insert(1, "one");
1692        if let Entry::Occupied(entry) = map.entry(1) {
1693            assert_eq!(entry.get(), &"one");
1694        }
1695    }
1696
1697    #[test]
1698    fn entry_occupied_insert() {
1699        let mut map: LiteMap<i32, &str> = LiteMap::new();
1700        map.insert(1, "one");
1701        if let Entry::Occupied(mut entry) = map.entry(1) {
1702            assert_eq!(entry.insert("uno"), "one");
1703        }
1704        assert_eq!(map.get(&1), Some(&"uno"));
1705    }
1706
1707    #[test]
1708    fn entry_vacant_key() {
1709        let mut map: LiteMap<i32, &str> = LiteMap::new();
1710        if let Entry::Vacant(entry) = map.entry(1) {
1711            assert_eq!(entry.key(), &1);
1712        }
1713    }
1714
1715    #[test]
1716    fn entry_or_insert() {
1717        let mut map: LiteMap<i32, &str> = LiteMap::new();
1718        map.entry(1).or_insert("one");
1719        assert_eq!(map.get(&1), Some(&"one"));
1720        map.entry(1).or_insert("uno");
1721        assert_eq!(map.get(&1), Some(&"one"));
1722    }
1723
1724    #[test]
1725    fn entry_or_insert_with() {
1726        let mut map: LiteMap<i32, &str> = LiteMap::new();
1727        map.entry(1).or_insert_with(|| "one");
1728        assert_eq!(map.get(&1), Some(&"one"));
1729        map.entry(1).or_insert_with(|| "uno");
1730        assert_eq!(map.get(&1), Some(&"one"));
1731    }
1732
1733    #[test]
1734    fn entry_or_default() {
1735        let mut map: LiteMap<i32, String> = LiteMap::new();
1736        map.entry(1).or_default();
1737        assert_eq!(map.get(&1), Some(&String::new()));
1738    }
1739
1740    #[test]
1741    fn entry_and_modify() {
1742        let mut map: LiteMap<i32, i32> = LiteMap::new();
1743        map.entry(1).or_insert(10);
1744        map.entry(1).and_modify(|v| *v += 5);
1745        assert_eq!(map.get(&1), Some(&15));
1746        map.entry(2).and_modify(|v| *v += 5).or_insert(20);
1747        assert_eq!(map.get(&2), Some(&20));
1748    }
1749}