1use 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;
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 #[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);
36pub struct LiteMap<K: ?Sized, V: ?Sized, S = alloc::vec::Vec<(K, V)>> {
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: ?Sized, V: ?Sized, S> ::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_receiver_is_total_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!(feature = "alloc", S = alloc::vec::Vec<(K, V)>);
39litemap_impl!(not(feature = "alloc"), S);
40
41#[cfg(feature = "alloc")]
42impl<K, V> LiteMap<K, V> {
43 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
53impl<K, V, S> LiteMap<K, V, S> {
54 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")]
67impl<K, V> LiteMap<K, V, Vec<(K, V)>> {
68 #[inline]
70 pub fn into_tuple_vec(self) -> Vec<(K, V)> {
71 self.values
72 }
73}
74
75impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
76where
77 S: StoreConstEmpty<K, V>,
78{
79 pub const fn new() -> Self {
81 Self {
82 values: S::EMPTY,
83 _key_type: PhantomData,
84 _value_type: PhantomData,
85 }
86 }
87}
88
89impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
90where
91 S: Store<K, V>,
92{
93 pub fn len(&self) -> usize {
95 self.values.lm_len()
96 }
97
98 pub fn is_empty(&self) -> bool {
100 self.values.lm_is_empty()
101 }
102
103 #[inline]
107 pub fn get_indexed(&self, index: usize) -> Option<(&K, &V)> {
108 self.values.lm_get(index)
109 }
110
111 #[inline]
124 pub fn first(&self) -> Option<(&K, &V)> {
125 self.values.lm_get(0)
126 }
127
128 #[inline]
141 pub fn last(&self) -> Option<(&K, &V)> {
142 self.values.lm_last()
143 }
144
145 #[cfg(feature = "alloc")]
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)] 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 #[cfg(feature = "alloc")]
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)] 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 #[cfg(feature = "alloc")]
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)] 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
261impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
262where
263 K: Ord,
264 S: Store<K, V>,
265{
266 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)] Ok(found) => Some(self.values.lm_get(found).unwrap().1),
285 Err(_) => None,
286 }
287 }
288
289 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 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 #[inline]
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
331impl<K: ?Sized, V: ?Sized, S> LiteMap<K, V, S>
332where
333 S: StoreSlice<K, V>,
334{
335 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 pub fn as_sliced(&self) -> LiteMap<K, V, &S::Slice> {
380 #[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 pub fn as_slice(&self) -> &S::Slice {
407 #[allow(clippy::unwrap_used)]
409 self.values.lm_get_range(0..self.len()).unwrap()
410 }
411}
412
413impl<'a, K: 'a, V: 'a, S> LiteMap<K, V, S>
414where
415 S: Store<K, V>,
416{
417 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)] 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 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)] 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 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)] 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
522impl<K, V, S> LiteMap<K, V, S>
523where
524 S: StoreMut<K, V>,
525{
526 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 pub fn clear(&mut self) {
537 self.values.lm_clear()
538 }
539
540 pub fn reserve(&mut self, additional: usize) {
547 self.values.lm_reserve(additional)
548 }
549}
550
551impl<K, V, S> LiteMap<K, V, S>
552where
553 K: Ord,
554 S: StoreMut<K, V>,
555{
556 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)] Ok(found) => Some(self.values.lm_get_mut(found).unwrap().1),
577 Err(_) => None,
578 }
579 }
580
581 #[must_use]
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 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
633 self.insert_save_key(key, value).map(|(_, v)| v)
634 }
635
636 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)] 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 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 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)] Ok((idx, self.values.lm_get(idx).unwrap().1))
740 }
741
742 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
765impl<K, V, S> LiteMap<K, V, S>
766where
767 K: Ord,
768 S: StoreIntoIterator<K, V> + StoreFromIterator<K, V>,
769{
770 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 self.values.lm_extend_end(other.values);
813 None
814 } else if self.first().map(|(k, _)| k) > other.last().map(|(k, _)| k) {
815 self.values.lm_extend_start(other.values);
817 None
818 } else {
819 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
839impl<K, V, S> Default for LiteMap<K, V, S>
840where
841 S: Store<K, V> + Default,
842{
843 fn default() -> Self {
844 Self {
845 values: S::default(),
846 _key_type: PhantomData,
847 _value_type: PhantomData,
848 }
849 }
850}
851impl<K, V, S> Index<&'_ K> for LiteMap<K, V, S>
852where
853 K: Ord,
854 S: Store<K, V>,
855{
856 type Output = V;
857 fn index(&self, key: &K) -> &V {
858 #[allow(clippy::panic)] match self.get(key) {
860 Some(v) => v,
861 None => { ::core::panicking::panic_fmt(format_args!("no entry found for key")); }panic!("no entry found for key"),
862 }
863 }
864}
865impl<K, V, S> IndexMut<&'_ K> for LiteMap<K, V, S>
866where
867 K: Ord,
868 S: StoreMut<K, V>,
869{
870 fn index_mut(&mut self, key: &K) -> &mut V {
871 #[allow(clippy::panic)] match self.get_mut(key) {
873 Some(v) => v,
874 None => { ::core::panicking::panic_fmt(format_args!("no entry found for key")); }panic!("no entry found for key"),
875 }
876 }
877}
878impl<K, V, S> FromIterator<(K, V)> for LiteMap<K, V, S>
879where
880 K: Ord,
881 S: StoreFromIterable<K, V>,
882{
883 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
889impl<'a, K: 'a, V: 'a, S> LiteMap<K, V, S>
890where
891 S: StoreIterable<'a, K, V>,
892{
893 pub fn iter(&'a self) -> impl DoubleEndedIterator<Item = (&'a K, &'a V)> {
895 self.values.lm_iter()
896 }
897
898 #[deprecated = "use keys() instead"]
900 pub fn iter_keys(&'a self) -> impl DoubleEndedIterator<Item = &'a K> {
901 self.values.lm_iter().map(|val| val.0)
902 }
903
904 #[deprecated = "use values() instead"]
906 pub fn iter_values(&'a self) -> impl DoubleEndedIterator<Item = &'a V> {
907 self.values.lm_iter().map(|val| val.1)
908 }
909
910 pub fn keys(&'a self) -> impl DoubleEndedIterator<Item = &'a K> {
912 self.values.lm_iter().map(|val| val.0)
913 }
914
915 pub fn values(&'a self) -> impl DoubleEndedIterator<Item = &'a V> {
917 self.values.lm_iter().map(|val| val.1)
918 }
919}
920
921impl<'a, K: 'a, V: 'a, S> LiteMap<K, V, S>
922where
923 S: StoreIterableMut<'a, K, V>,
924{
925 pub fn iter_mut(&'a mut self) -> impl DoubleEndedIterator<Item = (&'a K, &'a mut V)> {
927 self.values.lm_iter_mut()
928 }
929}
930
931impl<K, V, S> IntoIterator for LiteMap<K, V, S>
932where
933 S: StoreIntoIterator<K, V>,
934{
935 type Item = (K, V);
936 type IntoIter = S::KeyValueIntoIter;
937
938 fn into_iter(self) -> Self::IntoIter {
939 self.values.lm_into_iter()
940 }
941}
942
943impl<'a, K, V, S> IntoIterator for &'a LiteMap<K, V, S>
944where
945 S: StoreIterable<'a, K, V>,
946{
947 type Item = (&'a K, &'a V);
948 type IntoIter = S::KeyValueIter;
949
950 fn into_iter(self) -> Self::IntoIter {
951 self.values.lm_iter()
952 }
953}
954
955impl<'a, K, V, S> IntoIterator for &'a mut LiteMap<K, V, S>
956where
957 S: StoreIterableMut<'a, K, V>,
958{
959 type Item = (&'a K, &'a mut V);
960 type IntoIter = S::KeyValueIterMut;
961
962 fn into_iter(self) -> Self::IntoIter {
963 self.values.lm_iter_mut()
964 }
965}
966
967impl<K, V, S> LiteMap<K, V, S>
968where
969 S: StoreBulkMut<K, V>,
970{
971 #[inline]
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
1000impl<'a, K, V> LiteMap<K, V, &'a [(K, V)]> {
1001 #[inline]
1016 pub const fn const_len(&self) -> usize {
1017 self.values.len()
1018 }
1019
1020 #[inline]
1035 pub const fn const_is_empty(&self) -> bool {
1036 self.values.is_empty()
1037 }
1038
1039 #[inline]
1059 #[allow(clippy::indexing_slicing)] pub const fn const_get_indexed_or_panic(&self, index: usize) -> &'a (K, V) {
1061 &self.values[index]
1062 }
1063}
1064
1065const 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)] 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
1088impl<'a, V> LiteMap<&'a str, V, &'a [(&'a str, V)]> {
1089 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)] 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
1132impl<'a, V> LiteMap<&'a [u8], V, &'a [(&'a [u8], V)]> {
1133 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)] 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
1176macro_rules! impl_const_get_with_index_for_integer {
1177 ($integer:ty) => {
1178 impl<'a, V> LiteMap<$integer, V, &'a [($integer, V)]> {
1179 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)] 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
1205impl<'a, V> LiteMap<u8, V, &'a [(u8, V)]> {
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;
#[allow(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);
1206impl<'a, V> LiteMap<u16, V, &'a [(u16, V)]> {
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;
#[allow(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);
1207impl<'a, V> LiteMap<u32, V, &'a [(u32, V)]> {
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;
#[allow(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);
1208impl<'a, V> LiteMap<u64, V, &'a [(u64, V)]> {
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;
#[allow(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);
1209impl<'a, V> LiteMap<u128, V, &'a [(u128, V)]> {
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;
#[allow(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);
1210impl<'a, V> LiteMap<usize, V, &'a [(usize, V)]> {
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;
#[allow(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);
1211impl<'a, V> LiteMap<i8, V, &'a [(i8, V)]> {
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;
#[allow(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);
1212impl<'a, V> LiteMap<i16, V, &'a [(i16, V)]> {
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;
#[allow(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);
1213impl<'a, V> LiteMap<i32, V, &'a [(i32, V)]> {
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;
#[allow(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);
1214impl<'a, V> LiteMap<i64, V, &'a [(i64, V)]> {
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;
#[allow(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);
1215impl<'a, V> LiteMap<i128, V, &'a [(i128, V)]> {
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;
#[allow(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);
1216impl<'a, V> LiteMap<isize, V, &'a [(isize, V)]> {
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;
#[allow(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);
1217
1218#[allow(clippy::exhaustive_enums)]
1220pub enum Entry<'a, K, V, S> {
1221 Occupied(OccupiedEntry<'a, K, V, S>),
1222 Vacant(VacantEntry<'a, K, V, S>),
1223}
1224
1225impl<K, V, S> Debug for Entry<'_, K, V, S> {
1226 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1227 match self {
1228 Self::Occupied(arg0) => f.debug_tuple("Occupied").field(arg0).finish(),
1229 Self::Vacant(arg0) => f.debug_tuple("Vacant").field(arg0).finish(),
1230 }
1231 }
1232}
1233
1234pub struct OccupiedEntry<'a, K, V, S> {
1236 map: &'a mut LiteMap<K, V, S>,
1237 index: usize,
1238}
1239
1240impl<K, V, S> Debug for OccupiedEntry<'_, K, V, S> {
1241 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1242 f.debug_struct("OccupiedEntry")
1243 .field("index", &self.index)
1244 .finish()
1245 }
1246}
1247
1248pub struct VacantEntry<'a, K, V, S> {
1250 map: &'a mut LiteMap<K, V, S>,
1251 key: K,
1252 index: usize,
1253}
1254
1255impl<K, V, S> Debug for VacantEntry<'_, K, V, S> {
1256 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1257 f.debug_struct("VacantEntry")
1258 .field("index", &self.index)
1259 .finish()
1260 }
1261}
1262
1263impl<'a, K, V, S> Entry<'a, K, V, S>
1264where
1265 K: Ord,
1266 S: StoreMut<K, V>,
1267{
1268 pub fn or_insert(self, default: V) -> &'a mut V {
1271 match self {
1272 Entry::Occupied(entry) => entry.into_mut(),
1273 Entry::Vacant(entry) => entry.insert(default),
1274 }
1275 }
1276
1277 pub fn or_default(self) -> &'a mut V
1280 where
1281 V: Default,
1282 {
1283 self.or_insert(V::default())
1284 }
1285
1286 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
1289 match self {
1290 Entry::Occupied(entry) => entry.into_mut(),
1291 Entry::Vacant(entry) => entry.insert(default()),
1292 }
1293 }
1294
1295 pub fn and_modify<F>(self, f: F) -> Self
1298 where
1299 F: FnOnce(&mut V),
1300 {
1301 match self {
1302 Entry::Occupied(mut entry) => {
1303 f(entry.get_mut());
1304 Entry::Occupied(entry)
1305 }
1306 Entry::Vacant(entry) => Entry::Vacant(entry),
1307 }
1308 }
1309}
1310
1311impl<'a, K, V, S> OccupiedEntry<'a, K, V, S>
1312where
1313 K: Ord,
1314 S: StoreMut<K, V>,
1315{
1316 pub fn key(&self) -> &K {
1318 #[allow(clippy::unwrap_used)] self.map.values.lm_get(self.index).unwrap().0
1320 }
1321
1322 pub fn get(&self) -> &V {
1324 #[allow(clippy::unwrap_used)] self.map.values.lm_get(self.index).unwrap().1
1326 }
1327
1328 pub fn get_mut(&mut self) -> &mut V {
1330 #[allow(clippy::unwrap_used)] self.map.values.lm_get_mut(self.index).unwrap().1
1332 }
1333
1334 pub fn into_mut(self) -> &'a mut V {
1336 #[allow(clippy::unwrap_used)] self.map.values.lm_get_mut(self.index).unwrap().1
1338 }
1339
1340 pub fn insert(&mut self, value: V) -> V {
1342 mem::replace(self.get_mut(), value)
1343 }
1344
1345 pub fn remove(self) -> V {
1347 self.map.values.lm_remove(self.index).1
1348 }
1349}
1350
1351impl<'a, K, V, S> VacantEntry<'a, K, V, S>
1352where
1353 K: Ord,
1354 S: StoreMut<K, V>,
1355{
1356 pub fn key(&self) -> &K {
1358 &self.key
1359 }
1360
1361 pub fn insert(self, value: V) -> &'a mut V {
1363 self.map.values.lm_insert(self.index, self.key, value);
1366 #[allow(clippy::unwrap_used)] self.map.values.lm_get_mut(self.index).unwrap().1
1368 }
1369}
1370
1371impl<K, V, S> LiteMap<K, V, S>
1372where
1373 K: Ord,
1374 S: StoreMut<K, V>,
1375{
1376 pub fn entry(&mut self, key: K) -> Entry<K, V, S> {
1378 match self.values.lm_binary_search_by(|k| k.cmp(&key)) {
1379 Ok(index) => Entry::Occupied(OccupiedEntry { map: self, index }),
1380 Err(index) => Entry::Vacant(VacantEntry {
1381 map: self,
1382 key,
1383 index,
1384 }),
1385 }
1386 }
1387}
1388
1389impl<K, V, S> Extend<(K, V)> for LiteMap<K, V, S>
1390where
1391 K: Ord,
1392 S: StoreBulkMut<K, V>,
1393{
1394 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
1395 self.values.lm_extend(iter)
1396 }
1397}
1398
1399#[cfg(test)]
1400mod test {
1401 use super::*;
1402
1403 #[test]
1404 fn from_iterator() {
1405 let mut expected = LiteMap::with_capacity(4);
1406 expected.insert(1, "updated-one");
1407 expected.insert(2, "original-two");
1408 expected.insert(3, "original-three");
1409 expected.insert(4, "updated-four");
1410
1411 let actual = [
1412 (1, "original-one"),
1413 (2, "original-two"),
1414 (4, "original-four"),
1415 (4, "updated-four"),
1416 (1, "updated-one"),
1417 (3, "original-three"),
1418 ]
1419 .into_iter()
1420 .collect::<LiteMap<_, _>>();
1421
1422 assert_eq!(expected, actual);
1423 }
1424
1425 #[test]
1426 fn extend() {
1427 let mut expected: LiteMap<i32, &str> = LiteMap::with_capacity(4);
1428 expected.insert(1, "updated-one");
1429 expected.insert(2, "original-two");
1430 expected.insert(3, "original-three");
1431 expected.insert(4, "updated-four");
1432
1433 let mut actual: LiteMap<i32, &str> = LiteMap::new();
1434 actual.insert(1, "original-one");
1435 actual.extend([
1436 (2, "original-two"),
1437 (4, "original-four"),
1438 (4, "updated-four"),
1439 (1, "updated-one"),
1440 (3, "original-three"),
1441 ]);
1442
1443 assert_eq!(expected, actual);
1444 }
1445
1446 #[test]
1447 fn extend2() {
1448 let mut map: LiteMap<usize, &str> = LiteMap::new();
1449 map.extend(make_13());
1450 map.extend(make_24());
1451 map.extend(make_24());
1452 map.extend(make_46());
1453 map.extend(make_13());
1454 map.extend(make_46());
1455 assert_eq!(map.len(), 5);
1456 }
1457
1458 fn make_13() -> LiteMap<usize, &'static str> {
1459 let mut result = LiteMap::new();
1460 result.insert(1, "one");
1461 result.insert(3, "three");
1462 result
1463 }
1464
1465 fn make_24() -> LiteMap<usize, &'static str> {
1466 let mut result = LiteMap::new();
1467 result.insert(2, "TWO");
1468 result.insert(4, "FOUR");
1469 result
1470 }
1471
1472 fn make_46() -> LiteMap<usize, &'static str> {
1473 let mut result = LiteMap::new();
1474 result.insert(4, "four");
1475 result.insert(6, "six");
1476 result
1477 }
1478
1479 #[test]
1480 fn extend_from_litemap_append() {
1481 let mut map = LiteMap::new();
1482 map.extend_from_litemap(make_13())
1483 .ok_or(())
1484 .expect_err("Append to empty map");
1485 map.extend_from_litemap(make_46())
1486 .ok_or(())
1487 .expect_err("Append to lesser map");
1488 assert_eq!(map.len(), 4);
1489 }
1490
1491 #[test]
1492 fn extend_from_litemap_prepend() {
1493 let mut map = LiteMap::new();
1494 map.extend_from_litemap(make_46())
1495 .ok_or(())
1496 .expect_err("Prepend to empty map");
1497 map.extend_from_litemap(make_13())
1498 .ok_or(())
1499 .expect_err("Prepend to lesser map");
1500 assert_eq!(map.len(), 4);
1501 }
1502
1503 #[test]
1504 fn extend_from_litemap_insert() {
1505 let mut map = LiteMap::new();
1506 map.extend_from_litemap(make_13())
1507 .ok_or(())
1508 .expect_err("Append to empty map");
1509 map.extend_from_litemap(make_24())
1510 .ok_or(())
1511 .expect_err("Insert with no conflict");
1512 map.extend_from_litemap(make_46())
1513 .ok_or(())
1514 .expect("Insert with conflict");
1515 assert_eq!(map.len(), 5);
1516 }
1517
1518 #[test]
1519 fn test_const_cmp_bytes() {
1520 let strs = &["a", "aa", "abc", "abde", "bcd", "bcde"];
1521 for i in 0..strs.len() {
1522 for j in 0..strs.len() {
1523 let a = strs[i].as_bytes();
1524 let b = strs[j].as_bytes();
1525 assert_eq!(a.cmp(b), const_cmp_bytes(a, b));
1526 }
1527 }
1528 }
1529
1530 #[test]
1531 fn into_iterator() {
1532 let mut map = LiteMap::<_, _, Vec<(_, _)>>::new();
1533 map.insert(4, "four");
1534 map.insert(6, "six");
1535 let mut reference = vec![(6, "six"), (4, "four")];
1536
1537 for i in map {
1538 let r = reference.pop().unwrap();
1539 assert_eq!(r, i);
1540 }
1541 assert!(reference.is_empty());
1542 }
1543
1544 #[test]
1545 fn entry_insert() {
1546 let mut map: LiteMap<i32, &str> = LiteMap::new();
1547 assert!(matches!(map.entry(1), Entry::Vacant(_)));
1548 map.entry(1).or_insert("one");
1549 assert!(matches!(map.entry(1), Entry::Occupied(_)));
1550 assert_eq!(map.get(&1), Some(&"one"));
1551 }
1552
1553 #[test]
1554 fn entry_insert_with() {
1555 let mut map: LiteMap<i32, &str> = LiteMap::new();
1556 assert!(matches!(map.entry(1), Entry::Vacant(_)));
1557 map.entry(1).or_insert_with(|| "one");
1558 assert!(matches!(map.entry(1), Entry::Occupied(_)));
1559 assert_eq!(map.get(&1), Some(&"one"));
1560 }
1561
1562 #[test]
1563 fn entry_vacant_insert() {
1564 let mut map: LiteMap<i32, &str> = LiteMap::new();
1565 if let Entry::Vacant(entry) = map.entry(1) {
1566 entry.insert("one");
1567 }
1568 assert_eq!(map.get(&1), Some(&"one"));
1569 }
1570
1571 #[test]
1572 fn entry_occupied_get_mut() {
1573 let mut map: LiteMap<i32, &str> = LiteMap::new();
1574 map.insert(1, "one");
1575 if let Entry::Occupied(mut entry) = map.entry(1) {
1576 *entry.get_mut() = "uno";
1577 }
1578 assert_eq!(map.get(&1), Some(&"uno"));
1579 }
1580
1581 #[test]
1582 fn entry_occupied_remove() {
1583 let mut map: LiteMap<i32, &str> = LiteMap::new();
1584 map.insert(1, "one");
1585 if let Entry::Occupied(entry) = map.entry(1) {
1586 entry.remove();
1587 }
1588 assert_eq!(map.get(&1), None);
1589 }
1590
1591 #[test]
1592 fn entry_occupied_key() {
1593 let mut map: LiteMap<i32, &str> = LiteMap::new();
1594 map.insert(1, "one");
1595 if let Entry::Occupied(entry) = map.entry(1) {
1596 assert_eq!(entry.key(), &1);
1597 }
1598 }
1599
1600 #[test]
1601 fn entry_occupied_get() {
1602 let mut map: LiteMap<i32, &str> = LiteMap::new();
1603 map.insert(1, "one");
1604 if let Entry::Occupied(entry) = map.entry(1) {
1605 assert_eq!(entry.get(), &"one");
1606 }
1607 }
1608
1609 #[test]
1610 fn entry_occupied_insert() {
1611 let mut map: LiteMap<i32, &str> = LiteMap::new();
1612 map.insert(1, "one");
1613 if let Entry::Occupied(mut entry) = map.entry(1) {
1614 assert_eq!(entry.insert("uno"), "one");
1615 }
1616 assert_eq!(map.get(&1), Some(&"uno"));
1617 }
1618
1619 #[test]
1620 fn entry_vacant_key() {
1621 let mut map: LiteMap<i32, &str> = LiteMap::new();
1622 if let Entry::Vacant(entry) = map.entry(1) {
1623 assert_eq!(entry.key(), &1);
1624 }
1625 }
1626
1627 #[test]
1628 fn entry_or_insert() {
1629 let mut map: LiteMap<i32, &str> = LiteMap::new();
1630 map.entry(1).or_insert("one");
1631 assert_eq!(map.get(&1), Some(&"one"));
1632 map.entry(1).or_insert("uno");
1633 assert_eq!(map.get(&1), Some(&"one"));
1634 }
1635
1636 #[test]
1637 fn entry_or_insert_with() {
1638 let mut map: LiteMap<i32, &str> = LiteMap::new();
1639 map.entry(1).or_insert_with(|| "one");
1640 assert_eq!(map.get(&1), Some(&"one"));
1641 map.entry(1).or_insert_with(|| "uno");
1642 assert_eq!(map.get(&1), Some(&"one"));
1643 }
1644
1645 #[test]
1646 fn entry_or_default() {
1647 let mut map: LiteMap<i32, String> = LiteMap::new();
1648 map.entry(1).or_default();
1649 assert_eq!(map.get(&1), Some(&String::new()));
1650 }
1651
1652 #[test]
1653 fn entry_and_modify() {
1654 let mut map: LiteMap<i32, i32> = LiteMap::new();
1655 map.entry(1).or_insert(10);
1656 map.entry(1).and_modify(|v| *v += 5);
1657 assert_eq!(map.get(&1), Some(&15));
1658 map.entry(2).and_modify(|v| *v += 5).or_insert(20);
1659 assert_eq!(map.get(&2), Some(&20));
1660 }
1661}