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