use crate::Length;
use std::{collections::VecDeque, rc::Rc, sync::Arc};
pub trait Index: Length {
type Item<'a>
where
Self: 'a;
fn index(&self, index: usize) -> Option<Self::Item<'_>> {
(index < self.len()).then(||
unsafe { self.index_unchecked(index)})
}
fn index_checked(&self, index: usize) -> Self::Item<'_> {
#[cold]
#[inline(never)]
fn assert_failed(index: usize, len: usize) -> ! {
panic!("index (is {index}) should be < len (is {len})");
}
let len = self.len();
if index >= len {
assert_failed(index, len);
}
unsafe { self.index_unchecked(index) }
}
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_>;
}
impl<T> Index for Vec<T> {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T, const N: usize> Index for [T; N] {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T> Index for [T] {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T> Index for &[T] {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T> Index for &mut [T] {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T> Index for Box<[T]> {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T> Index for Rc<[T]> {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T> Index for Arc<[T]> {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
unsafe { self.get_unchecked(index) }
}
}
impl<T> Index for VecDeque<T> {
type Item<'a>
= &'a T
where
Self: 'a;
unsafe fn index_unchecked(&self, index: usize) -> Self::Item<'_> {
std::ops::Index::index(self, index)
}
}