index_vec/
idxslice.rs

1use super::*;
2
3/// A slice that only accepts indices of a specific type. Note that the intended
4/// usage is as `IndexSlice<I, [T]>`.
5///
6/// This is a thin wrapper around a `[T]`, to the point where the backing  is a
7/// public property (called `raw`). This is in part because I know this API is
8/// not a complete mirror of Vec's (patches welcome). In the worst case, you can
9/// always do what you need to the slice itself.
10///
11/// ## Some notes on the APIs
12///
13/// - Most of the Slice APIs are present.
14///     - Any that aren't can be trivially accessed on the underlying `raw`
15///       field, which is public.
16///
17/// - Apis that take or return usizes referring to the positions of items were
18///   replaced with ones that take Idx.
19///
20/// - Apis that take `R: RangeBounds<usize>` take an
21///   [`IdxRangeBounds<I>`][IdxRangeBounds], which is basically a
22///   `RangeBounds<I>`.
23/// - Apis that take `SliceIndex<usize>` take an
24///   [`IdxSliceIndex<I>`][IdxSliceIndex], which is basically a `SliceIndex<I>`.
25///
26/// - Most iterator functions where `the_iter().enumerate()` would refer to
27///   indices have been given `_enumerated` variants. E.g.
28///   [`IndexSlice::iter_enumerated`], etc. This is because
29///   `v.iter().enumerate()` would be `(usize, &T)`, but you want `(I, &T)`.
30///
31/// The following extensions are added:
32///
33/// - [`IndexSlice::indices`]: an Iterator over the indices of type `I`.
34/// - Various `enumerated` iterators mentioned earlier
35/// - [`IndexSlice::position`], [`IndexSlice::rposition`] as
36///   `self.iter().position()` will return a `Option<usize>`
37#[derive(Copy, Clone)]
38#[repr(transparent)]
39pub struct IndexSlice<I: Idx, T: ?Sized> {
40    _marker: PhantomData<fn(&I)>,
41    pub raw: T,
42}
43
44// Whether `IndexSlice` is `Send` depends only on the data,
45// not the phantom data.
46unsafe impl<I: Idx, T> Send for IndexSlice<I, [T]> where T: Send {}
47
48impl<I: Idx, T: fmt::Debug + ?Sized> fmt::Debug for IndexSlice<I, T> {
49    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
50        fmt::Debug::fmt(&self.raw, fmt)
51    }
52}
53/// `IndexBox<I, [T]>`: An alias for indexed boxed slice.
54pub type IndexBox<I, T> = Box<IndexSlice<I, T>>;
55
56type SliceMapped<Iter, I, T> = iter::Map<Iter, fn(&[T]) -> &IndexSlice<I, [T]>>;
57type SliceMappedMut<Iter, I, T> = iter::Map<Iter, fn(&mut [T]) -> &mut IndexSlice<I, [T]>>;
58
59impl<I: Idx, T> IndexSlice<I, [T]> {
60    /// Construct a new IdxSlice by wrapping an existing slice.
61    #[inline(always)]
62    pub fn new<S: AsRef<[T]> + ?Sized>(s: &S) -> &Self {
63        Self::from_slice(s.as_ref())
64    }
65
66    /// Construct a new mutable IdxSlice by wrapping an existing mutable slice.
67    #[inline(always)]
68    pub fn new_mut<S: AsMut<[T]> + ?Sized>(s: &mut S) -> &mut Self {
69        Self::from_slice_mut(s.as_mut())
70    }
71
72    /// Construct a new IdxSlice by wrapping an existing slice.
73    #[inline(always)]
74    pub const fn from_slice(s: &[T]) -> &Self {
75        unsafe { &*(s as *const [T] as *const Self) }
76    }
77
78    /// Construct a new mutable IdxSlice by wrapping an existing mutable slice.
79    #[inline(always)]
80    pub fn from_slice_mut(s: &mut [T]) -> &mut Self {
81        unsafe { &mut *(s as *mut [T] as *mut Self) }
82    }
83
84    /// Copies `self` into a new `IndexVec`.
85    #[inline]
86    pub fn to_vec(&self) -> IndexVec<I, T>
87    where
88        T: Clone,
89    {
90        IndexVec::from_vec(self.raw.to_vec())
91    }
92
93    /// Converts `self` into a vector without clones or allocation.
94    ///
95    /// The resulting vector can be converted back into a box via
96    /// `IndexVec<I, T>`'s `into_boxed_slice` method.
97    #[inline]
98    #[allow(clippy::wrong_self_convention)]
99    pub fn into_vec(self: Box<Self>) -> IndexVec<I, T> {
100        unsafe {
101            let len = self.len();
102            let b = Box::into_raw(self);
103            let xs = Vec::from_raw_parts(b as *mut T, len, len);
104            IndexVec::from_vec(xs)
105        }
106    }
107
108    /// Returns the underlying slice.
109    #[inline(always)]
110    pub fn as_raw_slice_mut(&mut self) -> &mut [T] {
111        &mut self.raw
112    }
113
114    /// Returns the underlying slice.
115    #[inline(always)]
116    pub const fn as_raw_slice(&self) -> &[T] {
117        &self.raw
118    }
119
120    /// Returns an unsafe mutable pointer to the slice's buffer.
121    #[inline]
122    pub fn as_mut_ptr(&mut self) -> *mut T {
123        self.raw.as_mut_ptr()
124    }
125
126    /// Returns an unsafe pointer to the slice's buffer.
127    #[inline]
128    pub const fn as_ptr(&self) -> *const T {
129        self.raw.as_ptr()
130    }
131
132    /// Return the index of the last element, or panic.
133    #[inline]
134    pub fn last_idx(&self) -> I {
135        // TODO: should this still be a panic even when `I` has disabled
136        // checking?
137        assert!(!self.is_empty());
138        I::from_usize(self.len() - 1)
139    }
140
141    /// Returns the length of our slice.
142    #[inline]
143    pub const fn len(&self) -> usize {
144        self.raw.len()
145    }
146
147    /// Returns the length of our slice as an `I`.
148    #[inline]
149    pub fn len_idx(&self) -> I {
150        I::from_usize(self.raw.len())
151    }
152
153    /// Returns true if we're empty.
154    #[inline]
155    pub const fn is_empty(&self) -> bool {
156        self.raw.is_empty()
157    }
158
159    /// Get a iterator over reverences to our values.
160    ///
161    /// See also [`IndexSlice::iter_enumerated`], which gives you indices (of the
162    /// correct type) as you iterate.
163    #[inline]
164    pub fn iter(&self) -> slice::Iter<'_, T> {
165        self.raw.iter()
166    }
167
168    /// Get a iterator over mut reverences to our values.
169    ///
170    /// See also [`IndexSlice::iter_mut_enumerated`], which gives you indices (of
171    /// the correct type) as you iterate.
172    #[inline]
173    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
174        self.raw.iter_mut()
175    }
176
177    /// Similar to `self.iter().enumerate()` but with indices of `I` and not
178    /// `usize`.
179    #[inline(always)]
180    pub fn iter_enumerated(&self) -> Enumerated<slice::Iter<'_, T>, I, &T> {
181        self.raw
182            .iter()
183            .enumerate()
184            .map(|(i, t)| (I::from_usize(i), t))
185    }
186
187    /// Get an interator over all our indices.
188    #[inline(always)]
189    pub fn indices(&self) -> iter::Map<Range<usize>, fn(usize) -> I> {
190        (0..self.raw.len()).map(I::from_usize)
191    }
192
193    /// Similar to `self.iter_mut().enumerate()` but with indices of `I` and not
194    /// `usize`.
195    #[inline(always)]
196    pub fn iter_mut_enumerated(&mut self) -> Enumerated<slice::IterMut<'_, T>, I, &mut T> {
197        self.raw
198            .iter_mut()
199            .enumerate()
200            .map(|(i, t)| (I::from_usize(i), t))
201    }
202
203    /// Forwards to the slice's `sort` implementation.
204    #[inline]
205    pub fn sort(&mut self)
206    where
207        T: Ord,
208    {
209        self.raw.sort()
210    }
211
212    /// Forwards to the slice's `sort_by` implementation.
213    #[inline]
214    pub fn sort_by<F: FnMut(&T, &T) -> core::cmp::Ordering>(&mut self, compare: F) {
215        self.raw.sort_by(compare)
216    }
217
218    /// Forwards to the slice's `sort_by_key` implementation.
219    #[inline]
220    pub fn sort_by_key<F: FnMut(&T) -> K, K: Ord>(&mut self, f: F) {
221        self.raw.sort_by_key(f)
222    }
223
224    /// Forwards to the slice's `sort_by_cached_key` implementation.
225    #[inline]
226    pub fn sort_by_cached_key<F: FnMut(&T) -> K, K: Ord>(&mut self, f: F) {
227        self.raw.sort_by_cached_key(f)
228    }
229
230    /// Forwards to the slice's `sort_unstable` implementation.
231    #[inline]
232    pub fn sort_unstable(&mut self)
233    where
234        T: Ord,
235    {
236        self.raw.sort_unstable()
237    }
238
239    /// Forwards to the slice's `sort_unstable_by` implementation.
240    #[inline]
241    pub fn sort_unstable_by<F: FnMut(&T, &T) -> core::cmp::Ordering>(&mut self, compare: F) {
242        self.raw.sort_unstable_by(compare)
243    }
244
245    /// Forwards to the slice's `sort_unstable_by_key` implementation.
246    #[inline]
247    pub fn sort_unstable_by_key<F: FnMut(&T) -> K, K: Ord>(&mut self, f: F) {
248        self.raw.sort_unstable_by_key(f)
249    }
250
251    /// Forwards to the slice's `ends_with` implementation.
252    #[inline]
253    pub fn ends_with<S: AsRef<[T]> + ?Sized>(&self, needle: &S) -> bool
254    where
255        T: PartialEq,
256    {
257        self.raw.ends_with(needle.as_ref())
258    }
259
260    /// Forwards to the slice's `starts_with` implementation.
261    #[inline]
262    pub fn starts_with<S: AsRef<[T]> + ?Sized>(&self, needle: &S) -> bool
263    where
264        T: PartialEq,
265    {
266        self.raw.starts_with(needle.as_ref())
267    }
268
269    /// Forwards to the slice's `contains` implementation.
270    #[inline]
271    pub fn contains(&self, x: &T) -> bool
272    where
273        T: PartialEq,
274    {
275        self.raw.contains(x)
276    }
277
278    /// Forwards to the slice's `reverse` implementation.
279    #[inline]
280    pub fn reverse(&mut self) {
281        self.raw.reverse()
282    }
283
284    /// Call `slice::binary_search` converting the indices it gives us back as
285    /// needed.
286    #[inline]
287    pub fn binary_search(&self, value: &T) -> Result<I, I>
288    where
289        T: Ord,
290    {
291        match self.raw.binary_search(value) {
292            Ok(i) => Ok(I::from_usize(i)),
293            Err(i) => Err(I::from_usize(i)),
294        }
295    }
296
297    /// Binary searches this sorted vec with a comparator function, converting
298    /// the indices it gives us back to our Idx type.
299    #[inline]
300    pub fn binary_search_by<'a, F: FnMut(&'a T) -> core::cmp::Ordering>(
301        &'a self,
302        f: F,
303    ) -> Result<I, I> {
304        match self.raw.binary_search_by(f) {
305            Ok(i) => Ok(I::from_usize(i)),
306            Err(i) => Err(I::from_usize(i)),
307        }
308    }
309
310    /// Copies all elements from `src` into `self`, using a memcpy.
311    #[inline]
312    pub fn copy_from_slice(&mut self, src: &Self)
313    where
314        T: Copy,
315    {
316        self.raw.copy_from_slice(&src.raw)
317    }
318
319    /// Copies the elements from `src` into `self`.
320    #[inline]
321    pub fn clone_from_slice(&mut self, src: &Self)
322    where
323        T: Clone,
324    {
325        self.raw.clone_from_slice(&src.raw)
326    }
327
328    /// Swaps all elements in `self` with those in `other`.
329    #[inline]
330    pub fn swap_with_slice(&mut self, other: &mut Self) {
331        self.raw.swap_with_slice(&mut other.raw)
332    }
333
334    /// Binary searches this sorted vec with a key extraction function, converting
335    /// the indices it gives us back to our Idx type.
336    #[inline]
337    pub fn binary_search_by_key<'a, B: Ord, F: FnMut(&'a T) -> B>(
338        &'a self,
339        b: &B,
340        f: F,
341    ) -> Result<I, I> {
342        match self.raw.binary_search_by_key(b, f) {
343            Ok(i) => Ok(I::from_usize(i)),
344            Err(i) => Err(I::from_usize(i)),
345        }
346    }
347    /// Searches for an element in an iterator, returning its index. This is
348    /// equivalent to `Iterator::position`, but returns `I` and not `usize`.
349    #[inline(always)]
350    pub fn position<F: FnMut(&T) -> bool>(&self, f: F) -> Option<I> {
351        self.raw.iter().position(f).map(I::from_usize)
352    }
353
354    /// Searches for an element in an iterator from the right, returning its
355    /// index. This is equivalent to `Iterator::position`, but returns `I` and
356    /// not `usize`.
357    #[inline(always)]
358    pub fn rposition<F: FnMut(&T) -> bool>(&self, f: F) -> Option<I> {
359        self.raw.iter().rposition(f).map(I::from_usize)
360    }
361
362    /// Swaps two elements in our vector.
363    #[inline]
364    pub fn swap(&mut self, a: I, b: I) {
365        self.raw.swap(a.index(), b.index())
366    }
367
368    /// Divides our slice into two at an index.
369    #[inline]
370    pub fn split_at(&self, a: I) -> (&Self, &Self) {
371        let (a, b) = self.raw.split_at(a.index());
372        (Self::from_slice(a), Self::from_slice(b))
373    }
374
375    /// Divides our slice into two at an index.
376    #[inline]
377    pub fn split_at_mut(&mut self, a: I) -> (&mut Self, &mut Self) {
378        let (a, b) = self.raw.split_at_mut(a.index());
379        (Self::new_mut(a), Self::new_mut(b))
380    }
381
382    /// Rotates our data in-place such that the first `mid` elements of the
383    /// slice move to the end while the last `self.len() - mid` elements move to
384    /// the front
385    #[inline]
386    pub fn rotate_left(&mut self, mid: I) {
387        self.raw.rotate_left(mid.index())
388    }
389
390    /// Rotates our data in-place such that the first `self.len() - k` elements
391    /// of the slice move to the end while the last `k` elements move to the
392    /// front
393    #[inline]
394    pub fn rotate_right(&mut self, k: I) {
395        self.raw.rotate_right(k.index())
396    }
397
398    /// Return the the last element, if we are not empty.
399    #[inline(always)]
400    pub const fn last(&self) -> Option<&T> {
401        self.raw.last()
402    }
403
404    /// Return the the last element, if we are not empty.
405    #[inline]
406    pub fn last_mut(&mut self) -> Option<&mut T> {
407        let i = self.len().checked_sub(1)?;
408        self.get_mut(I::from_usize(i))
409    }
410
411    /// Return the the first element, if we are not empty.
412    #[inline]
413    pub const fn first(&self) -> Option<&T> {
414        self.raw.first()
415    }
416
417    /// Return the the first element, if we are not empty.
418    #[inline]
419    pub fn first_mut(&mut self) -> Option<&mut T> {
420        self.get_mut(I::from_usize(0))
421    }
422
423    /// Copies elements from one part of the slice to another part of itself,
424    /// using a memmove.
425    #[inline]
426    pub fn copy_within<R: IdxRangeBounds<I>>(&mut self, src: R, dst: I)
427    where
428        T: Copy,
429    {
430        self.raw.copy_within(src.into_range(), dst.index())
431    }
432
433    /// Get a ref to the item at the provided index, or None for out of bounds.
434    #[inline]
435    pub fn get<J: IdxSliceIndex<I, T>>(&self, index: J) -> Option<&J::Output> {
436        index.get(self)
437    }
438
439    /// Get a mut ref to the item at the provided index, or None for out of
440    /// bounds
441    #[inline]
442    pub fn get_mut<J: IdxSliceIndex<I, T>>(&mut self, index: J) -> Option<&mut J::Output> {
443        index.get_mut(self)
444    }
445
446    /// Wraps the underlying slice's `windows` iterator with one that yields
447    /// `IndexSlice`s with the correct index type.
448    #[inline]
449    pub fn windows(&self, size: usize) -> SliceMapped<slice::Windows<'_, T>, I, T> {
450        self.raw.windows(size).map(IndexSlice::new)
451    }
452
453    /// Wraps the underlying slice's `chunks` iterator with one that yields
454    /// `IndexSlice`s with the correct index type.
455    #[inline]
456    pub fn chunks(&self, size: usize) -> SliceMapped<slice::Chunks<'_, T>, I, T> {
457        self.raw.chunks(size).map(IndexSlice::new)
458    }
459
460    /// Wraps the underlying slice's `chunks_mut` iterator with one that yields
461    /// `IndexSlice`s with the correct index type.
462    #[inline]
463    pub fn chunks_mut(&mut self, size: usize) -> SliceMappedMut<slice::ChunksMut<'_, T>, I, T> {
464        self.raw.chunks_mut(size).map(IndexSlice::new_mut)
465    }
466
467    /// Wraps the underlying slice's `chunks_exact` iterator with one that
468    /// yields `IndexSlice`s with the correct index type.
469    #[inline]
470    pub fn chunks_exact(&self, chunk_size: usize) -> SliceMapped<slice::ChunksExact<'_, T>, I, T> {
471        self.raw.chunks_exact(chunk_size).map(IndexSlice::new)
472    }
473
474    /// Wraps the underlying slice's `chunks_exact_mut` iterator with one that
475    /// yields `IndexSlice`s with the correct index type.
476    #[inline]
477    pub fn chunks_exact_mut(
478        &mut self,
479        chunk_size: usize,
480    ) -> SliceMappedMut<slice::ChunksExactMut<'_, T>, I, T> {
481        self.raw
482            .chunks_exact_mut(chunk_size)
483            .map(IndexSlice::new_mut)
484    }
485
486    /// Wraps the underlying slice's `rchunks` iterator with one that yields
487    /// `IndexSlice`s with the correct index type.
488    #[inline]
489    pub fn rchunks(&self, size: usize) -> SliceMapped<slice::RChunks<'_, T>, I, T> {
490        self.raw.rchunks(size).map(IndexSlice::new)
491    }
492
493    /// Wraps the underlying slice's `rchunks_mut` iterator with one that yields
494    /// `IndexSlice`s with the correct index type.
495    #[inline]
496    pub fn rchunks_mut(&mut self, size: usize) -> SliceMappedMut<slice::RChunksMut<'_, T>, I, T> {
497        self.raw.rchunks_mut(size).map(IndexSlice::new_mut)
498    }
499
500    /// Wraps the underlying slice's `rchunks_exact` iterator with one that
501    /// yields `IndexSlice`s with the correct index type.
502    #[inline]
503    pub fn rchunks_exact(
504        &self,
505        chunk_size: usize,
506    ) -> SliceMapped<slice::RChunksExact<'_, T>, I, T> {
507        self.raw.rchunks_exact(chunk_size).map(IndexSlice::new)
508    }
509
510    /// Wraps the underlying slice's `rchunks_exact_mut` iterator with one that
511    /// yields `IndexSlice`s with the correct index type.
512    #[inline]
513    pub fn rchunks_exact_mut(
514        &mut self,
515        chunk_size: usize,
516    ) -> SliceMappedMut<slice::RChunksExactMut<'_, T>, I, T> {
517        self.raw
518            .rchunks_exact_mut(chunk_size)
519            .map(IndexSlice::new_mut)
520    }
521
522    /// Wraps the underlying slice's `split` iterator with one that yields
523    /// `IndexSlice`s with the correct index type.
524    #[inline]
525    pub fn split<F: FnMut(&T) -> bool>(&self, f: F) -> SliceMapped<slice::Split<'_, T, F>, I, T> {
526        self.raw.split(f).map(IndexSlice::new)
527    }
528
529    /// Wraps the underlying slice's `split_mut` iterator with one that yields
530    /// `IndexSlice`s with the correct index type.
531    #[inline]
532    pub fn split_mut<F: FnMut(&T) -> bool>(
533        &mut self,
534        f: F,
535    ) -> SliceMappedMut<slice::SplitMut<'_, T, F>, I, T> {
536        self.raw.split_mut(f).map(IndexSlice::new_mut)
537    }
538
539    /// Wraps the underlying slice's `rsplit` iterator with one that yields
540    /// `IndexSlice`s with the correct index type.
541    #[inline]
542    pub fn rsplit<F: FnMut(&T) -> bool>(&self, f: F) -> SliceMapped<slice::RSplit<'_, T, F>, I, T> {
543        self.raw.rsplit(f).map(IndexSlice::new)
544    }
545
546    /// Wraps the underlying slice's `rsplit_mut` iterator with one that yields
547    /// `IndexSlice`s with the correct index type.
548    #[inline]
549    pub fn rsplit_mut<F: FnMut(&T) -> bool>(
550        &mut self,
551        f: F,
552    ) -> SliceMappedMut<slice::RSplitMut<'_, T, F>, I, T> {
553        self.raw.rsplit_mut(f).map(IndexSlice::new_mut)
554    }
555
556    /// Wraps the underlying slice's `splitn` iterator with one that yields
557    /// `IndexSlice`s with the correct index type.
558    #[inline]
559    pub fn splitn<F: FnMut(&T) -> bool>(
560        &self,
561        n: usize,
562        f: F,
563    ) -> SliceMapped<slice::SplitN<'_, T, F>, I, T> {
564        self.raw.splitn(n, f).map(IndexSlice::new)
565    }
566    /// Wraps the underlying slice's `splitn_mut` iterator with one that yields
567    /// `IndexSlice`s with the correct index type.
568    #[inline]
569    pub fn splitn_mut<F: FnMut(&T) -> bool>(
570        &mut self,
571        n: usize,
572        f: F,
573    ) -> SliceMappedMut<slice::SplitNMut<'_, T, F>, I, T> {
574        self.raw.splitn_mut(n, f).map(IndexSlice::new_mut)
575    }
576
577    /// Wraps the underlying slice's `rsplitn` iterator with one that yields
578    /// `IndexSlice`s with the correct index type.
579    #[inline]
580    pub fn rsplitn<F: FnMut(&T) -> bool>(
581        &self,
582        n: usize,
583        f: F,
584    ) -> SliceMapped<slice::RSplitN<'_, T, F>, I, T> {
585        self.raw.rsplitn(n, f).map(IndexSlice::new)
586    }
587
588    /// Wraps the underlying slice's `rsplitn_mut` iterator with one that yields
589    /// `IndexSlice`s with the correct index type.
590    #[inline]
591    pub fn rsplitn_mut<F: FnMut(&T) -> bool>(
592        &mut self,
593        n: usize,
594        f: F,
595    ) -> SliceMappedMut<slice::RSplitNMut<'_, T, F>, I, T> {
596        self.raw.rsplitn_mut(n, f).map(IndexSlice::new_mut)
597    }
598
599    /// Create a IdxSlice from its pointer and length.
600    ///
601    /// # Safety
602    ///
603    /// This is equivalent to `core::slice::from_raw_parts` and has the same
604    /// safety caveats.
605    #[inline]
606    pub unsafe fn from_raw_parts<'a>(data: *const T, len: usize) -> &'a Self {
607        Self::new(slice::from_raw_parts(data, len))
608    }
609
610    /// Create a mutable IdxSlice from its pointer and length.
611    ///
612    /// # Safety
613    ///
614    /// This is equivalent to `core::slice::from_raw_parts_mut` and has the same
615    /// safety caveats.
616    #[inline]
617    pub unsafe fn from_raw_parts_mut<'a>(data: *mut T, len: usize) -> &'a mut Self {
618        Self::new_mut(slice::from_raw_parts_mut(data, len))
619    }
620
621    /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
622    #[inline]
623    pub const fn split_first(&self) -> Option<(&T, &IndexSlice<I, [T]>)> {
624        if let Some((first, rem)) = self.raw.split_first() {
625            Some((first, Self::from_slice(rem)))
626        } else {
627            None
628        }
629    }
630
631    /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
632    #[inline]
633    pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut IndexSlice<I, [T]>)> {
634        if self.is_empty() {
635            None
636        } else {
637            let split = self.split_at_mut(I::from_usize(1));
638            Some((&mut split.0[I::from_usize(0)], split.1))
639        }
640    }
641
642    /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
643    #[inline]
644    pub const fn split_last(&self) -> Option<(&T, &IndexSlice<I, [T]>)> {
645        if let Some((last, rem)) = self.raw.split_last() {
646            Some((last, Self::from_slice(rem)))
647        } else {
648            None
649        }
650    }
651
652    /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
653    #[inline]
654    pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut IndexSlice<I, [T]>)> {
655        if self.is_empty() {
656            None
657        } else {
658            let last = self.last_idx();
659            let split = self.split_at_mut(last);
660            Some((&mut split.1[0], split.0))
661        }
662    }
663}
664
665impl<I: Idx, A, B> PartialEq<IndexSlice<I, [B]>> for IndexSlice<I, [A]>
666where
667    A: PartialEq<B>,
668{
669    #[inline]
670    fn eq(&self, other: &IndexSlice<I, [B]>) -> bool {
671        PartialEq::eq(&self.raw, &other.raw)
672    }
673    #[inline]
674    fn ne(&self, other: &IndexSlice<I, [B]>) -> bool {
675        PartialEq::ne(&self.raw, &other.raw)
676    }
677}
678
679impl<I: Idx, A: Eq> Eq for IndexSlice<I, [A]> {}
680
681impl<I: Idx, A, B> PartialEq<[B]> for IndexSlice<I, [A]>
682where
683    A: PartialEq<B>,
684{
685    #[inline]
686    fn eq(&self, other: &[B]) -> bool {
687        PartialEq::eq(&self.raw, other)
688    }
689    #[inline]
690    fn ne(&self, other: &[B]) -> bool {
691        PartialEq::ne(&self.raw, other)
692    }
693}
694
695impl<I: Idx, T: PartialOrd> PartialOrd for IndexSlice<I, [T]> {
696    #[inline]
697    fn partial_cmp(&self, other: &IndexSlice<I, [T]>) -> Option<core::cmp::Ordering> {
698        PartialOrd::partial_cmp(&self.raw, &other.raw)
699    }
700}
701
702impl<I: Idx, T: core::cmp::Ord> core::cmp::Ord for IndexSlice<I, [T]> {
703    #[inline]
704    fn cmp(&self, other: &IndexSlice<I, [T]>) -> core::cmp::Ordering {
705        core::cmp::Ord::cmp(&self.raw, &other.raw)
706    }
707}
708
709impl<I: Idx, T: core::hash::Hash> core::hash::Hash for IndexSlice<I, [T]> {
710    #[inline]
711    fn hash<H: core::hash::Hasher>(&self, h: &mut H) {
712        self.raw.hash(h)
713    }
714}
715
716impl<I: Idx, T> alloc::borrow::ToOwned for IndexSlice<I, [T]>
717where
718    T: Clone,
719{
720    type Owned = IndexVec<I, T>;
721    #[inline]
722    fn to_owned(&self) -> Self::Owned {
723        IndexVec::from(self.raw.to_vec())
724    }
725}
726
727impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, [T]> {
728    type Item = &'a T;
729    type IntoIter = slice::Iter<'a, T>;
730
731    #[inline]
732    fn into_iter(self) -> slice::Iter<'a, T> {
733        self.raw.iter()
734    }
735}
736
737impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, [T]> {
738    type Item = &'a mut T;
739    type IntoIter = slice::IterMut<'a, T>;
740
741    #[inline]
742    fn into_iter(self) -> slice::IterMut<'a, T> {
743        self.raw.iter_mut()
744    }
745}
746
747impl<I: Idx, T> Default for &IndexSlice<I, [T]> {
748    #[inline]
749    fn default() -> Self {
750        IndexSlice::new(&[])
751    }
752}
753
754impl<I: Idx, T> Default for &mut IndexSlice<I, [T]> {
755    #[inline]
756    fn default() -> Self {
757        IndexSlice::new_mut(&mut [])
758    }
759}
760
761impl<'a, I: Idx, T> From<&'a [T]> for &'a IndexSlice<I, [T]> {
762    #[inline]
763    fn from(a: &'a [T]) -> Self {
764        IndexSlice::new(a)
765    }
766}
767
768impl<'a, I: Idx, T> From<&'a mut [T]> for &'a mut IndexSlice<I, [T]> {
769    #[inline]
770    fn from(a: &'a mut [T]) -> Self {
771        IndexSlice::new_mut(a)
772    }
773}
774
775impl<I: Idx, T> From<Box<[T]>> for Box<IndexSlice<I, [T]>> {
776    #[inline]
777    fn from(b: Box<[T]>) -> Self {
778        unsafe { Box::from_raw(Box::into_raw(b) as *mut IndexSlice<I, [T]>) }
779    }
780}
781
782impl<I: Idx, A> AsRef<[A]> for IndexSlice<I, [A]> {
783    #[inline]
784    fn as_ref(&self) -> &[A] {
785        &self.raw
786    }
787}
788
789impl<I: Idx, A> AsMut<[A]> for IndexSlice<I, [A]> {
790    #[inline]
791    fn as_mut(&mut self) -> &mut [A] {
792        &mut self.raw
793    }
794}
795
796impl<I: Idx, T: Clone> Clone for Box<IndexSlice<I, [T]>> {
797    #[inline]
798    fn clone(&self) -> Self {
799        // Suboptimal, I think.
800        self.to_vec().into_boxed_slice()
801    }
802}
803
804impl<I: Idx, A> FromIterator<A> for Box<IndexSlice<I, [A]>> {
805    #[inline]
806    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
807        iter.into_iter()
808            .collect::<IndexVec<I, _>>()
809            .into_boxed_slice()
810    }
811}
812
813impl<I: Idx, A> IntoIterator for Box<IndexSlice<I, [A]>> {
814    type Item = A;
815    type IntoIter = vec::IntoIter<A>;
816    #[inline]
817    fn into_iter(self) -> Self::IntoIter {
818        let v: IndexVec<I, A> = self.into();
819        v.into_iter()
820    }
821}
822
823impl<I: Idx, A> Default for Box<IndexSlice<I, [A]>> {
824    #[inline(always)]
825    fn default() -> Self {
826        index_vec![].into()
827    }
828}