#![no_std]
#![warn(unsafe_op_in_unsafe_fn)]
mod index;
mod iter;
mod ops;
use core::fmt;
pub use crate::index::StrideIndex;
pub use crate::iter::{Iter, IterMut};
#[repr(transparent)]
pub struct Stride<T, const S: usize> {
data: [T],
}
impl<T, const S: usize> fmt::Debug for Stride<T, S>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl<T, const S: usize> Default for &Stride<T, S> {
fn default() -> Self {
Stride::new(&[])
}
}
impl<T, const S: usize> Default for &mut Stride<T, S> {
fn default() -> Self {
Stride::new_mut(&mut [])
}
}
impl<T, const S: usize> Stride<T, S> {
pub fn new(data: &[T]) -> &Self {
unsafe { &*(data as *const [T] as *const Self) }
}
pub fn new_mut(data: &mut [T]) -> &mut Self {
unsafe { &mut *(data as *mut [T] as *mut Self) }
}
pub const fn len(&self) -> usize {
self.data.len().div_ceil(S)
}
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
pub const fn as_ptr(&self) -> *const T {
self.data.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.data.as_mut_ptr()
}
pub fn get<I>(&self, index: I) -> Option<&I::Output>
where
I: StrideIndex<Stride<T, S>>,
{
index.get(self)
}
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
where
I: StrideIndex<Stride<T, S>>,
{
index.get_mut(self)
}
pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
where
I: StrideIndex<Self>,
{
unsafe { &*index.get_unchecked(self) }
}
pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
where
I: StrideIndex<Self>,
{
unsafe { &mut *index.get_unchecked_mut(self) }
}
pub fn first(&self) -> Option<&T> {
self.get(0)
}
pub fn first_mut(&mut self) -> Option<&mut T> {
self.get_mut(0)
}
pub fn last(&self) -> Option<&T> {
self.get(self.len().saturating_sub(1))
}
pub fn last_mut(&mut self) -> Option<&mut T> {
self.get_mut(self.len().saturating_sub(1))
}
pub fn swap(&mut self, a: usize, b: usize) {
self.data.swap(a * S, b * S)
}
pub fn iter(&self) -> Iter<'_, T, S> {
Iter::new(self)
}
pub fn iter_mut(&mut self) -> IterMut<'_, T, S> {
IterMut::new(self)
}
}
impl<T> Stride<T, 1> {
pub fn as_slice(&self) -> &[T] {
&self.data
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.data
}
}