1use std::fmt;
2use std::marker::PhantomData;
3use std::ops::{Index, IndexMut};
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 get<R: IntoSliceIdx<I, [T]>>(
109 &self,
110 index: R,
111 ) -> Option<&<R::Output as SliceIndex<[T]>>::Output> {
112 self.raw.get(index.into_slice_idx())
113 }
114
115 #[inline]
116 pub fn get_mut<R: IntoSliceIdx<I, [T]>>(
117 &mut self,
118 index: R,
119 ) -> Option<&mut <R::Output as SliceIndex<[T]>>::Output> {
120 self.raw.get_mut(index.into_slice_idx())
121 }
122
123 #[inline]
127 pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) {
128 let (ai, bi) = (a.index(), b.index());
129
130 match self.raw.get_disjoint_mut([ai, bi]) {
131 Ok([a, b]) => (a, b),
132 Err(OverlappingIndices) => panic!("Indices {ai:?} and {bi:?} are not disjoint!"),
133 Err(IndexOutOfBounds) => {
134 panic!("Some indices among ({ai:?}, {bi:?}) are out of bounds")
135 }
136 }
137 }
138
139 #[inline]
143 pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) {
144 let (ai, bi, ci) = (a.index(), b.index(), c.index());
145
146 match self.raw.get_disjoint_mut([ai, bi, ci]) {
147 Ok([a, b, c]) => (a, b, c),
148 Err(OverlappingIndices) => {
149 panic!("Indices {ai:?}, {bi:?} and {ci:?} are not disjoint!")
150 }
151 Err(IndexOutOfBounds) => {
152 panic!("Some indices among ({ai:?}, {bi:?}, {ci:?}) are out of bounds")
153 }
154 }
155 }
156
157 #[inline]
158 pub fn binary_search(&self, value: &T) -> Result<I, I>
159 where
160 T: Ord,
161 {
162 match self.raw.binary_search(value) {
163 Ok(i) => Ok(Idx::new(i)),
164 Err(i) => Err(Idx::new(i)),
165 }
166 }
167}
168
169impl<I: Idx, J: Idx> IndexSlice<I, J> {
170 pub fn invert_bijective_mapping(&self) -> IndexVec<J, I> {
178 debug_assert_eq!(
179 self.iter().map(|x| x.index() as u128).sum::<u128>(),
180 (0..self.len() as u128).sum::<u128>(),
181 "The values aren't 0..N in input {self:?}",
182 );
183
184 let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len());
185 for (i1, &i2) in self.iter_enumerated() {
186 inverse[i2] = i1;
187 }
188
189 debug_assert_eq!(
190 inverse.iter().map(|x| x.index() as u128).sum::<u128>(),
191 (0..inverse.len() as u128).sum::<u128>(),
192 "The values aren't 0..N in result {self:?}",
193 );
194
195 inverse
196 }
197}
198
199impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> {
200 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
201 fmt::Debug::fmt(&self.raw, fmt)
202 }
203}
204
205impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> Index<R> for IndexSlice<I, T> {
206 type Output = <R::Output as SliceIndex<[T]>>::Output;
207
208 #[inline]
209 fn index(&self, index: R) -> &Self::Output {
210 &self.raw[index.into_slice_idx()]
211 }
212}
213
214impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> IndexMut<R> for IndexSlice<I, T> {
215 #[inline]
216 fn index_mut(&mut self, index: R) -> &mut Self::Output {
217 &mut self.raw[index.into_slice_idx()]
218 }
219}
220
221impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> {
222 type Item = &'a T;
223 type IntoIter = slice::Iter<'a, T>;
224
225 #[inline]
226 fn into_iter(self) -> slice::Iter<'a, T> {
227 self.raw.iter()
228 }
229}
230
231impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> {
232 type Item = &'a mut T;
233 type IntoIter = slice::IterMut<'a, T>;
234
235 #[inline]
236 fn into_iter(self) -> slice::IterMut<'a, T> {
237 self.raw.iter_mut()
238 }
239}
240
241impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> {
242 type Owned = IndexVec<I, T>;
243
244 fn to_owned(&self) -> IndexVec<I, T> {
245 IndexVec::from_raw(self.raw.to_owned())
246 }
247
248 fn clone_into(&self, target: &mut IndexVec<I, T>) {
249 self.raw.clone_into(&mut target.raw)
250 }
251}
252
253impl<I: Idx, T> Default for &IndexSlice<I, T> {
254 #[inline]
255 fn default() -> Self {
256 IndexSlice::from_raw(Default::default())
257 }
258}
259
260impl<I: Idx, T> Default for &mut IndexSlice<I, T> {
261 #[inline]
262 fn default() -> Self {
263 IndexSlice::from_raw_mut(Default::default())
264 }
265}
266
267unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {}