1use std::fmt;
2use std::marker::PhantomData;
3use std::ops::{Index, IndexMut, RangeBounds};
4use std::slice::GetDisjointMutError::*;
5use std::slice::{self, SliceIndex};
6
7use crate::{Idx, IndexVec, IntoSliceIdx};
8
9#[derive(PartialEq, Eq, Hash)]
17#[repr(transparent)]
18pub struct IndexSlice<I: Idx, T> {
19 _marker: PhantomData<fn(&I)>,
20 pub raw: [T],
21}
22
23impl<I: Idx, T> IndexSlice<I, T> {
24 #[inline]
25 pub const fn empty<'a>() -> &'a Self {
26 Self::from_raw(&[])
27 }
28
29 #[inline]
30 pub const fn from_raw(raw: &[T]) -> &Self {
31 let ptr: *const [T] = raw;
32 unsafe { &*(ptr as *const Self) }
34 }
35
36 #[inline]
37 pub fn from_raw_mut(raw: &mut [T]) -> &mut Self {
38 let ptr: *mut [T] = raw;
39 unsafe { &mut *(ptr as *mut Self) }
41 }
42
43 #[inline]
44 pub const fn len(&self) -> usize {
45 self.raw.len()
46 }
47
48 #[inline]
49 pub const fn is_empty(&self) -> bool {
50 self.raw.is_empty()
51 }
52
53 #[inline]
58 pub fn next_index(&self) -> I {
59 I::new(self.len())
60 }
61
62 #[inline]
63 pub fn iter(&self) -> slice::Iter<'_, T> {
64 self.raw.iter()
65 }
66
67 #[inline]
68 pub fn iter_enumerated(&self) -> impl DoubleEndedIterator<Item = (I, &T)> + ExactSizeIterator {
69 let _ = I::new(self.len());
71 self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t))
72 }
73
74 #[inline]
75 pub fn indices(
76 &self,
77 ) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static {
78 let _ = I::new(self.len());
80 (0..self.len()).map(|n| I::new(n))
81 }
82
83 #[inline]
84 pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
85 self.raw.iter_mut()
86 }
87
88 #[inline]
89 pub fn iter_enumerated_mut(
90 &mut self,
91 ) -> impl DoubleEndedIterator<Item = (I, &mut T)> + ExactSizeIterator {
92 let _ = I::new(self.len());
94 self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t))
95 }
96
97 #[inline]
98 pub fn last_index(&self) -> Option<I> {
99 self.len().checked_sub(1).map(I::new)
100 }
101
102 #[inline]
103 pub fn swap(&mut self, a: I, b: I) {
104 self.raw.swap(a.index(), b.index())
105 }
106
107 #[inline]
108 pub fn copy_within(
109 &mut self,
110 src: impl IntoSliceIdx<I, [T], Output: RangeBounds<usize>>,
111 dest: I,
112 ) where
113 T: Copy,
114 {
115 self.raw.copy_within(src.into_slice_idx(), dest.index());
116 }
117
118 #[inline]
119 pub fn get<R: IntoSliceIdx<I, [T]>>(
120 &self,
121 index: R,
122 ) -> Option<&<R::Output as SliceIndex<[T]>>::Output> {
123 self.raw.get(index.into_slice_idx())
124 }
125
126 #[inline]
127 pub fn get_mut<R: IntoSliceIdx<I, [T]>>(
128 &mut self,
129 index: R,
130 ) -> Option<&mut <R::Output as SliceIndex<[T]>>::Output> {
131 self.raw.get_mut(index.into_slice_idx())
132 }
133
134 #[inline]
138 pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) {
139 let (ai, bi) = (a.index(), b.index());
140
141 match self.raw.get_disjoint_mut([ai, bi]) {
142 Ok([a, b]) => (a, b),
143 Err(OverlappingIndices) => panic!("Indices {ai:?} and {bi:?} are not disjoint!"),
144 Err(IndexOutOfBounds) => {
145 panic!("Some indices among ({ai:?}, {bi:?}) are out of bounds")
146 }
147 }
148 }
149
150 #[inline]
154 pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) {
155 let (ai, bi, ci) = (a.index(), b.index(), c.index());
156
157 match self.raw.get_disjoint_mut([ai, bi, ci]) {
158 Ok([a, b, c]) => (a, b, c),
159 Err(OverlappingIndices) => {
160 panic!("Indices {ai:?}, {bi:?} and {ci:?} are not disjoint!")
161 }
162 Err(IndexOutOfBounds) => {
163 panic!("Some indices among ({ai:?}, {bi:?}, {ci:?}) are out of bounds")
164 }
165 }
166 }
167
168 #[inline]
169 pub fn binary_search(&self, value: &T) -> Result<I, I>
170 where
171 T: Ord,
172 {
173 match self.raw.binary_search(value) {
174 Ok(i) => Ok(Idx::new(i)),
175 Err(i) => Err(Idx::new(i)),
176 }
177 }
178}
179
180impl<I: Idx, J: Idx> IndexSlice<I, J> {
181 pub fn invert_bijective_mapping(&self) -> IndexVec<J, I> {
186 debug_assert_eq!(
187 self.iter().map(|x| x.index() as u128).sum::<u128>(),
188 (0..self.len() as u128).sum::<u128>(),
189 "The values aren't 0..N in input {self:?}",
190 );
191
192 let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len());
193 for (i1, &i2) in self.iter_enumerated() {
194 inverse[i2] = i1;
195 }
196
197 debug_assert_eq!(
198 inverse.iter().map(|x| x.index() as u128).sum::<u128>(),
199 (0..inverse.len() as u128).sum::<u128>(),
200 "The values aren't 0..N in result {self:?}",
201 );
202
203 inverse
204 }
205}
206
207impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> {
208 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
209 fmt::Debug::fmt(&self.raw, fmt)
210 }
211}
212
213impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> Index<R> for IndexSlice<I, T> {
214 type Output = <R::Output as SliceIndex<[T]>>::Output;
215
216 #[inline]
217 fn index(&self, index: R) -> &Self::Output {
218 &self.raw[index.into_slice_idx()]
219 }
220}
221
222impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> IndexMut<R> for IndexSlice<I, T> {
223 #[inline]
224 fn index_mut(&mut self, index: R) -> &mut Self::Output {
225 &mut self.raw[index.into_slice_idx()]
226 }
227}
228
229impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> {
230 type Item = &'a T;
231 type IntoIter = slice::Iter<'a, T>;
232
233 #[inline]
234 fn into_iter(self) -> slice::Iter<'a, T> {
235 self.raw.iter()
236 }
237}
238
239impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> {
240 type Item = &'a mut T;
241 type IntoIter = slice::IterMut<'a, T>;
242
243 #[inline]
244 fn into_iter(self) -> slice::IterMut<'a, T> {
245 self.raw.iter_mut()
246 }
247}
248
249impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> {
250 type Owned = IndexVec<I, T>;
251
252 fn to_owned(&self) -> IndexVec<I, T> {
253 IndexVec::from_raw(self.raw.to_owned())
254 }
255
256 fn clone_into(&self, target: &mut IndexVec<I, T>) {
257 self.raw.clone_into(&mut target.raw)
258 }
259}
260
261impl<I: Idx, T> Default for &IndexSlice<I, T> {
262 #[inline]
263 fn default() -> Self {
264 IndexSlice::from_raw(Default::default())
265 }
266}
267
268impl<I: Idx, T> Default for &mut IndexSlice<I, T> {
269 #[inline]
270 fn default() -> Self {
271 IndexSlice::from_raw_mut(Default::default())
272 }
273}
274
275unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {}