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> {
189 debug_assert_eq!(
190 self.iter().map(|x| x.index() as u128).sum::<u128>(),
191 (0..self.len() as u128).sum::<u128>(),
192 "The values aren't 0..N in input {self:?}",
193 );
194
195 let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len());
196 for (i1, &i2) in self.iter_enumerated() {
197 inverse[i2] = i1;
198 }
199
200 debug_assert_eq!(
201 inverse.iter().map(|x| x.index() as u128).sum::<u128>(),
202 (0..inverse.len() as u128).sum::<u128>(),
203 "The values aren't 0..N in result {self:?}",
204 );
205
206 inverse
207 }
208}
209
210impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> {
211 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
212 fmt::Debug::fmt(&self.raw, fmt)
213 }
214}
215
216impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> Index<R> for IndexSlice<I, T> {
217 type Output = <R::Output as SliceIndex<[T]>>::Output;
218
219 #[inline]
220 fn index(&self, index: R) -> &Self::Output {
221 &self.raw[index.into_slice_idx()]
222 }
223}
224
225impl<I: Idx, T, R: IntoSliceIdx<I, [T]>> IndexMut<R> for IndexSlice<I, T> {
226 #[inline]
227 fn index_mut(&mut self, index: R) -> &mut Self::Output {
228 &mut self.raw[index.into_slice_idx()]
229 }
230}
231
232impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> {
233 type Item = &'a T;
234 type IntoIter = slice::Iter<'a, T>;
235
236 #[inline]
237 fn into_iter(self) -> slice::Iter<'a, T> {
238 self.raw.iter()
239 }
240}
241
242impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> {
243 type Item = &'a mut T;
244 type IntoIter = slice::IterMut<'a, T>;
245
246 #[inline]
247 fn into_iter(self) -> slice::IterMut<'a, T> {
248 self.raw.iter_mut()
249 }
250}
251
252impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> {
253 type Owned = IndexVec<I, T>;
254
255 fn to_owned(&self) -> IndexVec<I, T> {
256 IndexVec::from_raw(self.raw.to_owned())
257 }
258
259 fn clone_into(&self, target: &mut IndexVec<I, T>) {
260 self.raw.clone_into(&mut target.raw)
261 }
262}
263
264impl<I: Idx, T> Default for &IndexSlice<I, T> {
265 #[inline]
266 fn default() -> Self {
267 IndexSlice::from_raw(Default::default())
268 }
269}
270
271impl<I: Idx, T> Default for &mut IndexSlice<I, T> {
272 #[inline]
273 fn default() -> Self {
274 IndexSlice::from_raw_mut(Default::default())
275 }
276}
277
278unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {}