Coverage Report

Created: 2025-10-31 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.0/src/map.rs
Line
Count
Source
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    
44
    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.
57
0
    pub const fn from_sorted_store_unchecked(values: S) -> Self {
58
0
        Self {
59
0
            values,
60
0
            _key_type: PhantomData,
61
0
            _value_type: PhantomData,
62
0
        }
63
0
    }
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]
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`]
80
0
    pub const fn new() -> Self {
81
0
        Self {
82
0
            values: S::EMPTY,
83
0
            _key_type: PhantomData,
84
0
            _value_type: PhantomData,
85
0
        }
86
0
    }
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value, icu_locale_core::shortvec::ShortBoxSlice<(icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value)>>>::new
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::transform::key::Key, icu_locale_core::extensions::transform::value::Value>>::new
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`]
94
    pub fn len(&self) -> usize {
95
        self.values.lm_len()
96
    }
97
98
    /// Whether the [`LiteMap`] is empty
99
0
    pub fn is_empty(&self) -> bool {
100
0
        self.values.lm_is_empty()
101
0
    }
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value, icu_locale_core::shortvec::ShortBoxSlice<(icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value)>>>::is_empty
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::transform::key::Key, icu_locale_core::extensions::transform::value::Value>>::is_empty
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]
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]
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]
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")]
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")]
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")]
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
    /// ```
277
0
    pub fn get<Q>(&self, key: &Q) -> Option<&V>
278
0
    where
279
0
        K: Borrow<Q>,
280
0
        Q: Ord + ?Sized,
281
    {
282
0
        match self.find_index(key) {
283
            #[allow(clippy::unwrap_used)] // find_index returns a valid index
284
0
            Ok(found) => Some(self.values.lm_get(found).unwrap().1),
285
0
            Err(_) => None,
286
        }
287
0
    }
288
289
    /// Binary search the map with `predicate` to find a key, returning the value.
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
    /// ```
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]
322
0
    pub fn find_index<Q>(&self, key: &Q) -> Result<usize, usize>
323
0
    where
324
0
        K: Borrow<Q>,
325
0
        Q: Ord + ?Sized,
326
    {
327
0
        self.values.lm_binary_search_by(|k| k.borrow().cmp(key))
328
0
    }
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
    /// ```
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
    /// ```
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
    /// ```
406
    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
    /// ```
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
    /// ```
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
    /// ```
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
527
    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`]
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
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
    /// ```
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]
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
    /// ```
632
0
    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
633
0
        self.insert_save_key(key, value).map(|(_, v)| v)
634
0
    }
635
636
    /// Version of [`Self::insert()`] that returns both the key and the old value.
637
0
    fn insert_save_key(&mut self, key: K, value: V) -> Option<(K, V)> {
638
0
        match self.values.lm_binary_search_by(|k| k.cmp(&key)) {
639
            #[allow(clippy::unwrap_used)] // Index came from binary_search
640
0
            Ok(found) => Some((
641
0
                key,
642
0
                mem::replace(self.values.lm_get_mut(found).unwrap().1, value),
643
0
            )),
644
0
            Err(ins) => {
645
0
                self.values.lm_insert(ins, key, value);
646
0
                None
647
            }
648
        }
649
0
    }
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
    /// ```
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
    /// ```
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
    /// ```
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
    /// ```
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
{
843
0
    fn default() -> Self {
844
0
        Self {
845
0
            values: S::default(),
846
0
            _key_type: PhantomData,
847
0
            _value_type: PhantomData,
848
0
        }
849
0
    }
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value, icu_locale_core::shortvec::ShortBoxSlice<(icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value)>> as core::default::Default>::default
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::transform::key::Key, icu_locale_core::extensions::transform::value::Value> as core::default::Default>::default
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;
857
    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
{
870
    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
{
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
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
894
0
    pub fn iter(&'a self) -> impl DoubleEndedIterator<Item = (&'a K, &'a V)> {
895
0
        self.values.lm_iter()
896
0
    }
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value, icu_locale_core::shortvec::ShortBoxSlice<(icu_locale_core::extensions::unicode::key::Key, icu_locale_core::extensions::unicode::value::Value)>>>::iter
Unexecuted instantiation: <litemap::map::LiteMap<icu_locale_core::extensions::transform::key::Key, icu_locale_core::extensions::transform::value::Value>>::iter
897
898
    /// Produce an ordered iterator over keys
899
    #[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
    /// Produce an iterator over values, ordered by their keys
905
    #[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
    /// Produce an ordered iterator over keys
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
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
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
938
    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
950
    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
962
    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: StoreBulkMut<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]
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]
1016
    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]
1035
    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
1060
    pub const fn const_get_indexed_or_panic(&self, index: usize) -> &'a (K, V) {
1061
        &self.values[index]
1062
    }
1063
}
1064
1065
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
    /// ```
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
    /// ```
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
    Occupied(OccupiedEntry<'a, K, V, S>),
1222
    Vacant(VacantEntry<'a, K, V, S>),
1223
}
1224
1225
impl<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
1234
/// A view into an occupied entry in a `LiteMap`.
1235
pub struct OccupiedEntry<'a, K, V, S> {
1236
    map: &'a mut LiteMap<K, V, S>,
1237
    index: usize,
1238
}
1239
1240
impl<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
1248
/// A view into a vacant entry in a `LiteMap`.
1249
pub struct VacantEntry<'a, K, V, S> {
1250
    map: &'a mut LiteMap<K, V, S>,
1251
    key: K,
1252
    index: usize,
1253
}
1254
1255
impl<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
1263
impl<'a, K, V, S> Entry<'a, K, V, S>
1264
where
1265
    K: Ord,
1266
    S: StoreMut<K, V>,
1267
{
1268
    /// Ensures a value is in the entry by inserting the default value if empty,
1269
    /// and returns a mutable reference to the value in the entry.
1270
    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
    /// Ensures a value is in the entry by inserting the result of the default function if empty,
1278
    /// and returns a mutable reference to the value in the entry.
1279
    pub fn or_default(self) -> &'a mut V
1280
    where
1281
        V: Default,
1282
    {
1283
        self.or_insert(V::default())
1284
    }
1285
1286
    /// Ensures a value is in the entry by inserting the result of the default function if empty,
1287
    /// and returns a mutable reference to the value in the entry.
1288
    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
    /// Provides in-place mutable access to an occupied entry before any
1296
    /// potential inserts into the map.
1297
    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
1311
impl<'a, K, V, S> OccupiedEntry<'a, K, V, S>
1312
where
1313
    K: Ord,
1314
    S: StoreMut<K, V>,
1315
{
1316
    /// Gets a reference to the key in the entry.
1317
    pub fn key(&self) -> &K {
1318
        #[allow(clippy::unwrap_used)] // index is valid while we have a reference to the map
1319
        self.map.values.lm_get(self.index).unwrap().0
1320
    }
1321
1322
    /// Gets a reference to the value in the entry.
1323
    pub fn get(&self) -> &V {
1324
        #[allow(clippy::unwrap_used)] // index is valid while we have a reference to the map
1325
        self.map.values.lm_get(self.index).unwrap().1
1326
    }
1327
1328
    /// Gets a mutable reference to the value in the entry.
1329
    pub fn get_mut(&mut self) -> &mut V {
1330
        #[allow(clippy::unwrap_used)] // index is valid while we have a reference to the map
1331
        self.map.values.lm_get_mut(self.index).unwrap().1
1332
    }
1333
1334
    /// Converts the entry into a mutable reference to the value in the entry with a lifetime bound to the map.
1335
    pub fn into_mut(self) -> &'a mut V {
1336
        #[allow(clippy::unwrap_used)] // index is valid while we have a reference to the map
1337
        self.map.values.lm_get_mut(self.index).unwrap().1
1338
    }
1339
1340
    /// Sets the value of the entry, and returns the entry's old value.
1341
    pub fn insert(&mut self, value: V) -> V {
1342
        mem::replace(self.get_mut(), value)
1343
    }
1344
1345
    /// Takes the value out of the entry, and returns it.
1346
    pub fn remove(self) -> V {
1347
        self.map.values.lm_remove(self.index).1
1348
    }
1349
}
1350
1351
impl<'a, K, V, S> VacantEntry<'a, K, V, S>
1352
where
1353
    K: Ord,
1354
    S: StoreMut<K, V>,
1355
{
1356
    /// Gets a reference to the key that would be used when inserting a value through the `VacantEntry`.
1357
    pub fn key(&self) -> &K {
1358
        &self.key
1359
    }
1360
1361
    /// Sets the value of the entry with the `VacantEntry`'s key, and returns a mutable reference to it.
1362
    pub fn insert(self, value: V) -> &'a mut V {
1363
        // index is valid insert index that was found via binary search
1364
        // it's valid while we have a reference to the map
1365
        self.map.values.lm_insert(self.index, self.key, value);
1366
        #[allow(clippy::unwrap_used)] // we inserted at self.index above
1367
        self.map.values.lm_get_mut(self.index).unwrap().1
1368
    }
1369
}
1370
1371
impl<K, V, S> LiteMap<K, V, S>
1372
where
1373
    K: Ord,
1374
    S: StoreMut<K, V>,
1375
{
1376
    /// Gets the entry for the given key in the map for in-place manipulation.
1377
    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
1389
impl<K, V, S> Extend<(K, V)> for LiteMap<K, V, S>
1390
where
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)]
1400
mod 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
}