indexmap/map/
slice.rs

1use super::{
2    Bucket, Entries, IndexMap, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values,
3    ValuesMut,
4};
5use crate::util::{slice_eq, try_simplify_range};
6use crate::GetDisjointMutError;
7
8use alloc::boxed::Box;
9use alloc::vec::Vec;
10use core::cmp::Ordering;
11use core::fmt;
12use core::hash::{Hash, Hasher};
13use core::ops::{self, Bound, Index, IndexMut, RangeBounds};
14
15/// A dynamically-sized slice of key-value pairs in an [`IndexMap`].
16///
17/// This supports indexed operations much like a `[(K, V)]` slice,
18/// but not any hashed operations on the map keys.
19///
20/// Unlike `IndexMap`, `Slice` does consider the order for [`PartialEq`]
21/// and [`Eq`], and it also implements [`PartialOrd`], [`Ord`], and [`Hash`].
22#[repr(transparent)]
23pub struct Slice<K, V> {
24    pub(crate) entries: [Bucket<K, V>],
25}
26
27// SAFETY: `Slice<K, V>` is a transparent wrapper around `[Bucket<K, V>]`,
28// and reference lifetimes are bound together in function signatures.
29#[allow(unsafe_code)]
30impl<K, V> Slice<K, V> {
31    pub(super) const fn from_slice(entries: &[Bucket<K, V>]) -> &Self {
32        unsafe { &*(entries as *const [Bucket<K, V>] as *const Self) }
33    }
34
35    pub(super) fn from_mut_slice(entries: &mut [Bucket<K, V>]) -> &mut Self {
36        unsafe { &mut *(entries as *mut [Bucket<K, V>] as *mut Self) }
37    }
38
39    pub(super) fn from_boxed(entries: Box<[Bucket<K, V>]>) -> Box<Self> {
40        unsafe { Box::from_raw(Box::into_raw(entries) as *mut Self) }
41    }
42
43    fn into_boxed(self: Box<Self>) -> Box<[Bucket<K, V>]> {
44        unsafe { Box::from_raw(Box::into_raw(self) as *mut [Bucket<K, V>]) }
45    }
46}
47
48impl<K, V> Slice<K, V> {
49    pub(crate) fn into_entries(self: Box<Self>) -> Vec<Bucket<K, V>> {
50        self.into_boxed().into_vec()
51    }
52
53    /// Returns an empty slice.
54    pub const fn new<'a>() -> &'a Self {
55        Self::from_slice(&[])
56    }
57
58    /// Returns an empty mutable slice.
59    pub fn new_mut<'a>() -> &'a mut Self {
60        Self::from_mut_slice(&mut [])
61    }
62
63    /// Return the number of key-value pairs in the map slice.
64    #[inline]
65    pub const fn len(&self) -> usize {
66        self.entries.len()
67    }
68
69    /// Returns true if the map slice contains no elements.
70    #[inline]
71    pub const fn is_empty(&self) -> bool {
72        self.entries.is_empty()
73    }
74
75    /// Get a key-value pair by index.
76    ///
77    /// Valid indices are `0 <= index < self.len()`.
78    pub fn get_index(&self, index: usize) -> Option<(&K, &V)> {
79        self.entries.get(index).map(Bucket::refs)
80    }
81
82    /// Get a key-value pair by index, with mutable access to the value.
83    ///
84    /// Valid indices are `0 <= index < self.len()`.
85    pub fn get_index_mut(&mut self, index: usize) -> Option<(&K, &mut V)> {
86        self.entries.get_mut(index).map(Bucket::ref_mut)
87    }
88
89    /// Returns a slice of key-value pairs in the given range of indices.
90    ///
91    /// Valid indices are `0 <= index < self.len()`.
92    pub fn get_range<R: RangeBounds<usize>>(&self, range: R) -> Option<&Self> {
93        let range = try_simplify_range(range, self.entries.len())?;
94        self.entries.get(range).map(Slice::from_slice)
95    }
96
97    /// Returns a mutable slice of key-value pairs in the given range of indices.
98    ///
99    /// Valid indices are `0 <= index < self.len()`.
100    pub fn get_range_mut<R: RangeBounds<usize>>(&mut self, range: R) -> Option<&mut Self> {
101        let range = try_simplify_range(range, self.entries.len())?;
102        self.entries.get_mut(range).map(Slice::from_mut_slice)
103    }
104
105    /// Get the first key-value pair.
106    pub fn first(&self) -> Option<(&K, &V)> {
107        self.entries.first().map(Bucket::refs)
108    }
109
110    /// Get the first key-value pair, with mutable access to the value.
111    pub fn first_mut(&mut self) -> Option<(&K, &mut V)> {
112        self.entries.first_mut().map(Bucket::ref_mut)
113    }
114
115    /// Get the last key-value pair.
116    pub fn last(&self) -> Option<(&K, &V)> {
117        self.entries.last().map(Bucket::refs)
118    }
119
120    /// Get the last key-value pair, with mutable access to the value.
121    pub fn last_mut(&mut self) -> Option<(&K, &mut V)> {
122        self.entries.last_mut().map(Bucket::ref_mut)
123    }
124
125    /// Divides one slice into two at an index.
126    ///
127    /// ***Panics*** if `index > len`.
128    pub fn split_at(&self, index: usize) -> (&Self, &Self) {
129        let (first, second) = self.entries.split_at(index);
130        (Self::from_slice(first), Self::from_slice(second))
131    }
132
133    /// Divides one mutable slice into two at an index.
134    ///
135    /// ***Panics*** if `index > len`.
136    pub fn split_at_mut(&mut self, index: usize) -> (&mut Self, &mut Self) {
137        let (first, second) = self.entries.split_at_mut(index);
138        (Self::from_mut_slice(first), Self::from_mut_slice(second))
139    }
140
141    /// Returns the first key-value pair and the rest of the slice,
142    /// or `None` if it is empty.
143    pub fn split_first(&self) -> Option<((&K, &V), &Self)> {
144        if let [first, rest @ ..] = &self.entries {
145            Some((first.refs(), Self::from_slice(rest)))
146        } else {
147            None
148        }
149    }
150
151    /// Returns the first key-value pair and the rest of the slice,
152    /// with mutable access to the value, or `None` if it is empty.
153    pub fn split_first_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> {
154        if let [first, rest @ ..] = &mut self.entries {
155            Some((first.ref_mut(), Self::from_mut_slice(rest)))
156        } else {
157            None
158        }
159    }
160
161    /// Returns the last key-value pair and the rest of the slice,
162    /// or `None` if it is empty.
163    pub fn split_last(&self) -> Option<((&K, &V), &Self)> {
164        if let [rest @ .., last] = &self.entries {
165            Some((last.refs(), Self::from_slice(rest)))
166        } else {
167            None
168        }
169    }
170
171    /// Returns the last key-value pair and the rest of the slice,
172    /// with mutable access to the value, or `None` if it is empty.
173    pub fn split_last_mut(&mut self) -> Option<((&K, &mut V), &mut Self)> {
174        if let [rest @ .., last] = &mut self.entries {
175            Some((last.ref_mut(), Self::from_mut_slice(rest)))
176        } else {
177            None
178        }
179    }
180
181    /// Return an iterator over the key-value pairs of the map slice.
182    pub fn iter(&self) -> Iter<'_, K, V> {
183        Iter::new(&self.entries)
184    }
185
186    /// Return an iterator over the key-value pairs of the map slice.
187    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
188        IterMut::new(&mut self.entries)
189    }
190
191    /// Return an iterator over the keys of the map slice.
192    pub fn keys(&self) -> Keys<'_, K, V> {
193        Keys::new(&self.entries)
194    }
195
196    /// Return an owning iterator over the keys of the map slice.
197    pub fn into_keys(self: Box<Self>) -> IntoKeys<K, V> {
198        IntoKeys::new(self.into_entries())
199    }
200
201    /// Return an iterator over the values of the map slice.
202    pub fn values(&self) -> Values<'_, K, V> {
203        Values::new(&self.entries)
204    }
205
206    /// Return an iterator over mutable references to the the values of the map slice.
207    pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
208        ValuesMut::new(&mut self.entries)
209    }
210
211    /// Return an owning iterator over the values of the map slice.
212    pub fn into_values(self: Box<Self>) -> IntoValues<K, V> {
213        IntoValues::new(self.into_entries())
214    }
215
216    /// Search over a sorted map for a key.
217    ///
218    /// Returns the position where that key is present, or the position where it can be inserted to
219    /// maintain the sort. See [`slice::binary_search`] for more details.
220    ///
221    /// Computes in **O(log(n))** time, which is notably less scalable than looking the key up in
222    /// the map this is a slice from using [`IndexMap::get_index_of`], but this can also position
223    /// missing keys.
224    pub fn binary_search_keys(&self, x: &K) -> Result<usize, usize>
225    where
226        K: Ord,
227    {
228        self.binary_search_by(|p, _| p.cmp(x))
229    }
230
231    /// Search over a sorted map with a comparator function.
232    ///
233    /// Returns the position where that value is present, or the position where it can be inserted
234    /// to maintain the sort. See [`slice::binary_search_by`] for more details.
235    ///
236    /// Computes in **O(log(n))** time.
237    #[inline]
238    pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
239    where
240        F: FnMut(&'a K, &'a V) -> Ordering,
241    {
242        self.entries.binary_search_by(move |a| f(&a.key, &a.value))
243    }
244
245    /// Search over a sorted map with an extraction function.
246    ///
247    /// Returns the position where that value is present, or the position where it can be inserted
248    /// to maintain the sort. See [`slice::binary_search_by_key`] for more details.
249    ///
250    /// Computes in **O(log(n))** time.
251    #[inline]
252    pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
253    where
254        F: FnMut(&'a K, &'a V) -> B,
255        B: Ord,
256    {
257        self.binary_search_by(|k, v| f(k, v).cmp(b))
258    }
259
260    /// Returns the index of the partition point of a sorted map according to the given predicate
261    /// (the index of the first element of the second partition).
262    ///
263    /// See [`slice::partition_point`] for more details.
264    ///
265    /// Computes in **O(log(n))** time.
266    #[must_use]
267    pub fn partition_point<P>(&self, mut pred: P) -> usize
268    where
269        P: FnMut(&K, &V) -> bool,
270    {
271        self.entries
272            .partition_point(move |a| pred(&a.key, &a.value))
273    }
274
275    /// Get an array of `N` key-value pairs by `N` indices
276    ///
277    /// Valid indices are *0 <= index < self.len()* and each index needs to be unique.
278    pub fn get_disjoint_mut<const N: usize>(
279        &mut self,
280        indices: [usize; N],
281    ) -> Result<[(&K, &mut V); N], GetDisjointMutError> {
282        let indices = indices.map(Some);
283        let key_values = self.get_disjoint_opt_mut(indices)?;
284        Ok(key_values.map(Option::unwrap))
285    }
286
287    #[allow(unsafe_code)]
288    pub(crate) fn get_disjoint_opt_mut<const N: usize>(
289        &mut self,
290        indices: [Option<usize>; N],
291    ) -> Result<[Option<(&K, &mut V)>; N], GetDisjointMutError> {
292        // SAFETY: Can't allow duplicate indices as we would return several mutable refs to the same data.
293        let len = self.len();
294        for i in 0..N {
295            if let Some(idx) = indices[i] {
296                if idx >= len {
297                    return Err(GetDisjointMutError::IndexOutOfBounds);
298                } else if indices[..i].contains(&Some(idx)) {
299                    return Err(GetDisjointMutError::OverlappingIndices);
300                }
301            }
302        }
303
304        let entries_ptr = self.entries.as_mut_ptr();
305        let out = indices.map(|idx_opt| {
306            match idx_opt {
307                Some(idx) => {
308                    // SAFETY: The base pointer is valid as it comes from a slice and the reference is always
309                    // in-bounds & unique as we've already checked the indices above.
310                    let kv = unsafe { (*(entries_ptr.add(idx))).ref_mut() };
311                    Some(kv)
312                }
313                None => None,
314            }
315        });
316
317        Ok(out)
318    }
319}
320
321impl<'a, K, V> IntoIterator for &'a Slice<K, V> {
322    type IntoIter = Iter<'a, K, V>;
323    type Item = (&'a K, &'a V);
324
325    fn into_iter(self) -> Self::IntoIter {
326        self.iter()
327    }
328}
329
330impl<'a, K, V> IntoIterator for &'a mut Slice<K, V> {
331    type IntoIter = IterMut<'a, K, V>;
332    type Item = (&'a K, &'a mut V);
333
334    fn into_iter(self) -> Self::IntoIter {
335        self.iter_mut()
336    }
337}
338
339impl<K, V> IntoIterator for Box<Slice<K, V>> {
340    type IntoIter = IntoIter<K, V>;
341    type Item = (K, V);
342
343    fn into_iter(self) -> Self::IntoIter {
344        IntoIter::new(self.into_entries())
345    }
346}
347
348impl<K, V> Default for &'_ Slice<K, V> {
349    fn default() -> Self {
350        Slice::from_slice(&[])
351    }
352}
353
354impl<K, V> Default for &'_ mut Slice<K, V> {
355    fn default() -> Self {
356        Slice::from_mut_slice(&mut [])
357    }
358}
359
360impl<K, V> Default for Box<Slice<K, V>> {
361    fn default() -> Self {
362        Slice::from_boxed(Box::default())
363    }
364}
365
366impl<K: Clone, V: Clone> Clone for Box<Slice<K, V>> {
367    fn clone(&self) -> Self {
368        Slice::from_boxed(self.entries.to_vec().into_boxed_slice())
369    }
370}
371
372impl<K: Copy, V: Copy> From<&Slice<K, V>> for Box<Slice<K, V>> {
373    fn from(slice: &Slice<K, V>) -> Self {
374        Slice::from_boxed(Box::from(&slice.entries))
375    }
376}
377
378impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Slice<K, V> {
379    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380        f.debug_list().entries(self).finish()
381    }
382}
383
384impl<K, V, K2, V2> PartialEq<Slice<K2, V2>> for Slice<K, V>
385where
386    K: PartialEq<K2>,
387    V: PartialEq<V2>,
388{
389    fn eq(&self, other: &Slice<K2, V2>) -> bool {
390        slice_eq(&self.entries, &other.entries, |b1, b2| {
391            b1.key == b2.key && b1.value == b2.value
392        })
393    }
394}
395
396impl<K, V, K2, V2> PartialEq<[(K2, V2)]> for Slice<K, V>
397where
398    K: PartialEq<K2>,
399    V: PartialEq<V2>,
400{
401    fn eq(&self, other: &[(K2, V2)]) -> bool {
402        slice_eq(&self.entries, other, |b, t| b.key == t.0 && b.value == t.1)
403    }
404}
405
406impl<K, V, K2, V2> PartialEq<Slice<K2, V2>> for [(K, V)]
407where
408    K: PartialEq<K2>,
409    V: PartialEq<V2>,
410{
411    fn eq(&self, other: &Slice<K2, V2>) -> bool {
412        slice_eq(self, &other.entries, |t, b| t.0 == b.key && t.1 == b.value)
413    }
414}
415
416impl<K, V, K2, V2, const N: usize> PartialEq<[(K2, V2); N]> for Slice<K, V>
417where
418    K: PartialEq<K2>,
419    V: PartialEq<V2>,
420{
421    fn eq(&self, other: &[(K2, V2); N]) -> bool {
422        <Self as PartialEq<[_]>>::eq(self, other)
423    }
424}
425
426impl<K, V, const N: usize, K2, V2> PartialEq<Slice<K2, V2>> for [(K, V); N]
427where
428    K: PartialEq<K2>,
429    V: PartialEq<V2>,
430{
431    fn eq(&self, other: &Slice<K2, V2>) -> bool {
432        <[_] as PartialEq<_>>::eq(self, other)
433    }
434}
435
436impl<K: Eq, V: Eq> Eq for Slice<K, V> {}
437
438impl<K: PartialOrd, V: PartialOrd> PartialOrd for Slice<K, V> {
439    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
440        self.iter().partial_cmp(other)
441    }
442}
443
444impl<K: Ord, V: Ord> Ord for Slice<K, V> {
445    fn cmp(&self, other: &Self) -> Ordering {
446        self.iter().cmp(other)
447    }
448}
449
450impl<K: Hash, V: Hash> Hash for Slice<K, V> {
451    fn hash<H: Hasher>(&self, state: &mut H) {
452        self.len().hash(state);
453        for (key, value) in self {
454            key.hash(state);
455            value.hash(state);
456        }
457    }
458}
459
460impl<K, V> Index<usize> for Slice<K, V> {
461    type Output = V;
462
463    fn index(&self, index: usize) -> &V {
464        &self.entries[index].value
465    }
466}
467
468impl<K, V> IndexMut<usize> for Slice<K, V> {
469    fn index_mut(&mut self, index: usize) -> &mut V {
470        &mut self.entries[index].value
471    }
472}
473
474// We can't have `impl<I: RangeBounds<usize>> Index<I>` because that conflicts
475// both upstream with `Index<usize>` and downstream with `Index<&Q>`.
476// Instead, we repeat the implementations for all the core range types.
477macro_rules! impl_index {
478    ($($range:ty),*) => {$(
479        impl<K, V, S> Index<$range> for IndexMap<K, V, S> {
480            type Output = Slice<K, V>;
481
482            fn index(&self, range: $range) -> &Self::Output {
483                Slice::from_slice(&self.as_entries()[range])
484            }
485        }
486
487        impl<K, V, S> IndexMut<$range> for IndexMap<K, V, S> {
488            fn index_mut(&mut self, range: $range) -> &mut Self::Output {
489                Slice::from_mut_slice(&mut self.as_entries_mut()[range])
490            }
491        }
492
493        impl<K, V> Index<$range> for Slice<K, V> {
494            type Output = Slice<K, V>;
495
496            fn index(&self, range: $range) -> &Self {
497                Self::from_slice(&self.entries[range])
498            }
499        }
500
501        impl<K, V> IndexMut<$range> for Slice<K, V> {
502            fn index_mut(&mut self, range: $range) -> &mut Self {
503                Self::from_mut_slice(&mut self.entries[range])
504            }
505        }
506    )*}
507}
508impl_index!(
509    ops::Range<usize>,
510    ops::RangeFrom<usize>,
511    ops::RangeFull,
512    ops::RangeInclusive<usize>,
513    ops::RangeTo<usize>,
514    ops::RangeToInclusive<usize>,
515    (Bound<usize>, Bound<usize>)
516);
517
518#[cfg(test)]
519mod tests {
520    use super::*;
521
522    #[test]
523    fn slice_index() {
524        fn check(
525            vec_slice: &[(i32, i32)],
526            map_slice: &Slice<i32, i32>,
527            sub_slice: &Slice<i32, i32>,
528        ) {
529            assert_eq!(map_slice as *const _, sub_slice as *const _);
530            itertools::assert_equal(
531                vec_slice.iter().copied(),
532                map_slice.iter().map(|(&k, &v)| (k, v)),
533            );
534            itertools::assert_equal(vec_slice.iter().map(|(k, _)| k), map_slice.keys());
535            itertools::assert_equal(vec_slice.iter().map(|(_, v)| v), map_slice.values());
536        }
537
538        let vec: Vec<(i32, i32)> = (0..10).map(|i| (i, i * i)).collect();
539        let map: IndexMap<i32, i32> = vec.iter().cloned().collect();
540        let slice = map.as_slice();
541
542        // RangeFull
543        check(&vec[..], &map[..], &slice[..]);
544
545        for i in 0usize..10 {
546            // Index
547            assert_eq!(vec[i].1, map[i]);
548            assert_eq!(vec[i].1, slice[i]);
549            assert_eq!(map[&(i as i32)], map[i]);
550            assert_eq!(map[&(i as i32)], slice[i]);
551
552            // RangeFrom
553            check(&vec[i..], &map[i..], &slice[i..]);
554
555            // RangeTo
556            check(&vec[..i], &map[..i], &slice[..i]);
557
558            // RangeToInclusive
559            check(&vec[..=i], &map[..=i], &slice[..=i]);
560
561            // (Bound<usize>, Bound<usize>)
562            let bounds = (Bound::Excluded(i), Bound::Unbounded);
563            check(&vec[i + 1..], &map[bounds], &slice[bounds]);
564
565            for j in i..=10 {
566                // Range
567                check(&vec[i..j], &map[i..j], &slice[i..j]);
568            }
569
570            for j in i..10 {
571                // RangeInclusive
572                check(&vec[i..=j], &map[i..=j], &slice[i..=j]);
573            }
574        }
575    }
576
577    #[test]
578    fn slice_index_mut() {
579        fn check_mut(
580            vec_slice: &[(i32, i32)],
581            map_slice: &mut Slice<i32, i32>,
582            sub_slice: &mut Slice<i32, i32>,
583        ) {
584            assert_eq!(map_slice, sub_slice);
585            itertools::assert_equal(
586                vec_slice.iter().copied(),
587                map_slice.iter_mut().map(|(&k, &mut v)| (k, v)),
588            );
589            itertools::assert_equal(
590                vec_slice.iter().map(|&(_, v)| v),
591                map_slice.values_mut().map(|&mut v| v),
592            );
593        }
594
595        let vec: Vec<(i32, i32)> = (0..10).map(|i| (i, i * i)).collect();
596        let mut map: IndexMap<i32, i32> = vec.iter().cloned().collect();
597        let mut map2 = map.clone();
598        let slice = map2.as_mut_slice();
599
600        // RangeFull
601        check_mut(&vec[..], &mut map[..], &mut slice[..]);
602
603        for i in 0usize..10 {
604            // IndexMut
605            assert_eq!(&mut map[i], &mut slice[i]);
606
607            // RangeFrom
608            check_mut(&vec[i..], &mut map[i..], &mut slice[i..]);
609
610            // RangeTo
611            check_mut(&vec[..i], &mut map[..i], &mut slice[..i]);
612
613            // RangeToInclusive
614            check_mut(&vec[..=i], &mut map[..=i], &mut slice[..=i]);
615
616            // (Bound<usize>, Bound<usize>)
617            let bounds = (Bound::Excluded(i), Bound::Unbounded);
618            check_mut(&vec[i + 1..], &mut map[bounds], &mut slice[bounds]);
619
620            for j in i..=10 {
621                // Range
622                check_mut(&vec[i..j], &mut map[i..j], &mut slice[i..j]);
623            }
624
625            for j in i..10 {
626                // RangeInclusive
627                check_mut(&vec[i..=j], &mut map[i..=j], &mut slice[i..=j]);
628            }
629        }
630    }
631}