ra_ap_rustc_index/
slice.rs

1use std::marker::PhantomData;
2use std::ops::{Index, IndexMut};
3use std::{fmt, slice};
4
5use crate::{Idx, IndexVec};
6
7/// A view into contiguous `T`s, indexed by `I` rather than by `usize`.
8///
9/// One common pattern you'll see is code that uses [`IndexVec::from_elem`]
10/// to create the storage needed for a particular "universe" (aka the set of all
11/// the possible keys that need an associated value) then passes that working
12/// area as `&mut IndexSlice<I, T>` to clarify that nothing will be added nor
13/// removed during processing (and, as a bonus, to chase fewer pointers).
14#[derive(PartialEq, Eq, Hash)]
15#[repr(transparent)]
16pub struct IndexSlice<I: Idx, T> {
17    _marker: PhantomData<fn(&I)>,
18    pub raw: [T],
19}
20
21impl<I: Idx, T> IndexSlice<I, T> {
22    #[inline]
23    pub const fn empty<'a>() -> &'a Self {
24        Self::from_raw(&[])
25    }
26
27    #[inline]
28    pub const fn from_raw(raw: &[T]) -> &Self {
29        let ptr: *const [T] = raw;
30        // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice
31        unsafe { &*(ptr as *const Self) }
32    }
33
34    #[inline]
35    pub fn from_raw_mut(raw: &mut [T]) -> &mut Self {
36        let ptr: *mut [T] = raw;
37        // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice
38        unsafe { &mut *(ptr as *mut Self) }
39    }
40
41    #[inline]
42    pub const fn len(&self) -> usize {
43        self.raw.len()
44    }
45
46    #[inline]
47    pub const fn is_empty(&self) -> bool {
48        self.raw.is_empty()
49    }
50
51    /// Gives the next index that will be assigned when `push` is called.
52    ///
53    /// Manual bounds checks can be done using `idx < slice.next_index()`
54    /// (as opposed to `idx.index() < slice.len()`).
55    #[inline]
56    pub fn next_index(&self) -> I {
57        I::new(self.len())
58    }
59
60    #[inline]
61    pub fn iter(&self) -> slice::Iter<'_, T> {
62        self.raw.iter()
63    }
64
65    #[inline]
66    pub fn iter_enumerated(
67        &self,
68    ) -> impl DoubleEndedIterator<Item = (I, &T)> + ExactSizeIterator + '_ {
69        self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t))
70    }
71
72    #[inline]
73    pub fn indices(
74        &self,
75    ) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static {
76        (0..self.len()).map(|n| I::new(n))
77    }
78
79    #[inline]
80    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
81        self.raw.iter_mut()
82    }
83
84    #[inline]
85    pub fn iter_enumerated_mut(
86        &mut self,
87    ) -> impl DoubleEndedIterator<Item = (I, &mut T)> + ExactSizeIterator + '_ {
88        self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t))
89    }
90
91    #[inline]
92    pub fn last_index(&self) -> Option<I> {
93        self.len().checked_sub(1).map(I::new)
94    }
95
96    #[inline]
97    pub fn swap(&mut self, a: I, b: I) {
98        self.raw.swap(a.index(), b.index())
99    }
100
101    #[inline]
102    pub fn get(&self, index: I) -> Option<&T> {
103        self.raw.get(index.index())
104    }
105
106    #[inline]
107    pub fn get_mut(&mut self, index: I) -> Option<&mut T> {
108        self.raw.get_mut(index.index())
109    }
110
111    /// Returns mutable references to two distinct elements, `a` and `b`.
112    ///
113    /// Panics if `a == b`.
114    #[inline]
115    pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) {
116        let (ai, bi) = (a.index(), b.index());
117        assert!(ai != bi);
118
119        if ai < bi {
120            let (c1, c2) = self.raw.split_at_mut(bi);
121            (&mut c1[ai], &mut c2[0])
122        } else {
123            let (c2, c1) = self.pick2_mut(b, a);
124            (c1, c2)
125        }
126    }
127
128    /// Returns mutable references to three distinct elements.
129    ///
130    /// Panics if the elements are not distinct.
131    #[inline]
132    pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) {
133        let (ai, bi, ci) = (a.index(), b.index(), c.index());
134        assert!(ai != bi && bi != ci && ci != ai);
135        let len = self.raw.len();
136        assert!(ai < len && bi < len && ci < len);
137        let ptr = self.raw.as_mut_ptr();
138        unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) }
139    }
140
141    #[inline]
142    pub fn binary_search(&self, value: &T) -> Result<I, I>
143    where
144        T: Ord,
145    {
146        match self.raw.binary_search(value) {
147            Ok(i) => Ok(Idx::new(i)),
148            Err(i) => Err(Idx::new(i)),
149        }
150    }
151}
152
153impl<I: Idx, J: Idx> IndexSlice<I, J> {
154    /// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`,
155    /// assuming the values in `self` are a permutation of `0..self.len()`.
156    ///
157    /// This is used to go between `memory_index` (source field order to memory order)
158    /// and `inverse_memory_index` (memory order to source field order).
159    /// See also `FieldsShape::Arbitrary::memory_index` for more details.
160    // FIXME(eddyb) build a better abstraction for permutations, if possible.
161    pub fn invert_bijective_mapping(&self) -> IndexVec<J, I> {
162        debug_assert_eq!(
163            self.iter().map(|x| x.index() as u128).sum::<u128>(),
164            (0..self.len() as u128).sum::<u128>(),
165            "The values aren't 0..N in input {self:?}",
166        );
167
168        let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len());
169        for (i1, &i2) in self.iter_enumerated() {
170            inverse[i2] = i1;
171        }
172
173        debug_assert_eq!(
174            inverse.iter().map(|x| x.index() as u128).sum::<u128>(),
175            (0..inverse.len() as u128).sum::<u128>(),
176            "The values aren't 0..N in result {self:?}",
177        );
178
179        inverse
180    }
181}
182
183impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> {
184    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
185        fmt::Debug::fmt(&self.raw, fmt)
186    }
187}
188
189impl<I: Idx, T> Index<I> for IndexSlice<I, T> {
190    type Output = T;
191
192    #[inline]
193    fn index(&self, index: I) -> &T {
194        &self.raw[index.index()]
195    }
196}
197
198impl<I: Idx, T> IndexMut<I> for IndexSlice<I, T> {
199    #[inline]
200    fn index_mut(&mut self, index: I) -> &mut T {
201        &mut self.raw[index.index()]
202    }
203}
204
205impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> {
206    type Item = &'a T;
207    type IntoIter = slice::Iter<'a, T>;
208
209    #[inline]
210    fn into_iter(self) -> slice::Iter<'a, T> {
211        self.raw.iter()
212    }
213}
214
215impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> {
216    type Item = &'a mut T;
217    type IntoIter = slice::IterMut<'a, T>;
218
219    #[inline]
220    fn into_iter(self) -> slice::IterMut<'a, T> {
221        self.raw.iter_mut()
222    }
223}
224
225impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> {
226    type Owned = IndexVec<I, T>;
227
228    fn to_owned(&self) -> IndexVec<I, T> {
229        IndexVec::from_raw(self.raw.to_owned())
230    }
231
232    fn clone_into(&self, target: &mut IndexVec<I, T>) {
233        self.raw.clone_into(&mut target.raw)
234    }
235}
236
237impl<I: Idx, T> Default for &IndexSlice<I, T> {
238    #[inline]
239    fn default() -> Self {
240        IndexSlice::from_raw(Default::default())
241    }
242}
243
244impl<I: Idx, T> Default for &mut IndexSlice<I, T> {
245    #[inline]
246    fn default() -> Self {
247        IndexSlice::from_raw_mut(Default::default())
248    }
249}
250
251// Whether `IndexSlice` is `Send` depends only on the data,
252// not the phantom data.
253unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {}