#[cfg(feature = "alloc")]
use alloc::boxed::Box;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use anyhow::{bail, Result};
#[impl_tools::autoimpl(for<T: trait + ?Sized> &T, &mut T)]
#[cfg_attr(feature = "alloc", impl_tools::autoimpl(for<T: trait + ?Sized> Box<T>))]
pub trait Sequence {
type Item: Copy;
type Iter<'a>: Iterator<Item = Self::Item>
where
Self::Item: 'a,
Self: 'a;
fn len(&self) -> usize;
unsafe fn get_unchecked(&self, index: usize) -> Self::Item;
fn get(&self, index: usize) -> Result<Self::Item> {
if index >= self.len() {
bail!(
"The index {} is out of bounds for the Sequence of length {}",
index,
self.len(),
);
}
Ok(unsafe { self.get_unchecked(index) })
}
fn is_empty(&self) -> bool {
self.len() == 0
}
fn iter(&self) -> Self::Iter<'_>;
}
#[impl_tools::autoimpl(for<T: trait + ?Sized> &mut T)]
#[cfg_attr(feature = "alloc", impl_tools::autoimpl(for<T: trait + ?Sized> Box<T>))]
pub trait SequenceMut: Sequence {
unsafe fn set_unchecked(&mut self, index: usize, value: Self::Item);
fn set(&mut self, index: usize, value: Self::Item) -> Result<()> {
if index >= self.len() {
bail!(
"The index {} is out of bounds for the Sequence of length {}",
index,
self.len(),
);
}
unsafe { self.set_unchecked(index, value) };
Ok(())
}
}
#[impl_tools::autoimpl(for<T: trait + ?Sized> &mut T)]
#[cfg_attr(feature = "alloc", impl_tools::autoimpl(for<T: trait + ?Sized> Box<T>))]
pub trait SequenceGrowable: SequenceMut {
fn resize(&mut self, new_len: usize, value: Self::Item);
fn push(&mut self, value: Self::Item);
fn pop(&mut self) -> Option<Self::Item>;
fn clear(&mut self);
fn extend_from<S: Sequence<Item = Self::Item>>(&mut self, other: &S);
}
impl<T: Copy, const N: usize> Sequence for [T; N] {
type Item = T;
type Iter<'a>
= core::iter::Copied<core::slice::Iter<'a, Self::Item>>
where
Self::Item: 'a,
Self: 'a;
#[inline(always)]
fn len(&self) -> usize {
N
}
#[inline(always)]
unsafe fn get_unchecked(&self, index: usize) -> T {
debug_assert!(index < self.len(), "{} {}", index, self.len());
<[T; N]>::get_unchecked(self, index)
}
#[inline(always)]
fn iter(&self) -> Self::Iter<'_> {
self.as_ref().iter().copied()
}
}
impl<T: Copy> Sequence for [T] {
type Item = T;
type Iter<'b>
= core::iter::Copied<core::slice::Iter<'b, Self::Item>>
where
Self::Item: 'b,
Self: 'b;
#[inline(always)]
fn len(&self) -> usize {
<[T]>::len(self)
}
#[inline(always)]
unsafe fn get_unchecked(&self, index: usize) -> T {
debug_assert!(index < self.len(), "{} {}", index, self.len());
*<[T]>::get_unchecked(self, index)
}
#[inline(always)]
fn iter(&self) -> Self::Iter<'_> {
<[T]>::iter(self).copied()
}
}
impl<T: Copy, const N: usize> SequenceMut for [T; N] {
#[inline(always)]
unsafe fn set_unchecked(&mut self, index: usize, value: T) {
debug_assert!(index < self.len(), "{} {}", index, self.len());
*self.get_unchecked_mut(index) = value;
}
}
impl<T: Copy> SequenceMut for [T] {
#[inline(always)]
unsafe fn set_unchecked(&mut self, index: usize, value: T) {
debug_assert!(index < self.len(), "{} {}", index, self.len());
*<[T]>::get_unchecked_mut(self, index) = value;
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<T: Copy> Sequence for Vec<T> {
type Item = T;
type Iter<'a>
= core::iter::Copied<core::slice::Iter<'a, Self::Item>>
where
Self::Item: 'a,
Self: 'a;
#[inline(always)]
fn len(&self) -> usize {
<Vec<T>>::len(self)
}
#[inline(always)]
unsafe fn get_unchecked(&self, index: usize) -> T {
debug_assert!(index < self.len(), "{} {}", index, self.len());
*<[T]>::get_unchecked(self, index)
}
#[inline(always)]
fn iter(&self) -> Self::Iter<'_> {
<[T]>::iter(self).copied()
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<T: Copy> SequenceMut for Vec<T> {
#[inline(always)]
unsafe fn set_unchecked(&mut self, index: usize, value: T) {
debug_assert!(index < self.len(), "{} {}", index, self.len());
*<[T]>::get_unchecked_mut(self, index) = value;
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
impl<T: Copy> SequenceGrowable for Vec<T> {
#[inline(always)]
fn resize(&mut self, new_len: usize, value: Self::Item) {
<Vec<T>>::resize(self, new_len, value);
}
#[inline(always)]
fn push(&mut self, value: Self::Item) {
<Vec<T>>::push(self, value);
}
#[inline(always)]
fn pop(&mut self) -> Option<Self::Item> {
<Vec<T>>::pop(self)
}
#[inline(always)]
fn clear(&mut self) {
<Vec<T>>::clear(self);
}
#[inline(always)]
fn extend_from<S: Sequence<Item = Self::Item>>(&mut self, other: &S) {
for i in 0..other.len() {
self.push(other.get(i).unwrap());
}
}
}