use super::base_operations::{BaseItem, Shape};
pub trait UnsafeRandomAccessByValue<const NDIM: usize>: BaseItem {
unsafe fn get_value_unchecked(&self, multi_index: [usize; NDIM]) -> Self::Item;
}
pub trait UnsafeRandom1DAccessByValue: BaseItem {
unsafe fn get_value_1d_unchecked(&self, index: usize) -> Self::Item;
}
pub trait UnsafeRandomAccessByRef<const NDIM: usize>: BaseItem {
unsafe fn get_unchecked(&self, multi_index: [usize; NDIM]) -> &Self::Item;
}
pub trait UnsafeRandom1DAccessByRef: BaseItem {
unsafe fn get_1d_unchecked(&self, index: usize) -> &Self::Item;
}
pub trait UnsafeRandomAccessMut<const NDIM: usize>: BaseItem {
unsafe fn get_unchecked_mut(&mut self, multi_index: [usize; NDIM]) -> &mut Self::Item;
}
pub trait UnsafeRandom1DAccessMut: BaseItem {
unsafe fn get_1d_unchecked_mut(&mut self, index: usize) -> &mut Self::Item;
}
pub unsafe trait UnsafeDisjointRandom1DAccessMut: UnsafeRandom1DAccessMut {}
pub trait RandomAccessByValue<const NDIM: usize>: BaseItem {
fn get_value(&self, multi_index: [usize; NDIM]) -> Option<Self::Item>;
}
pub trait RandomAccessByRef<const NDIM: usize>: BaseItem {
fn get(&self, multi_index: [usize; NDIM]) -> Option<&Self::Item>;
}
pub trait RandomAccessMut<const NDIM: usize>: BaseItem {
fn get_mut(&mut self, multi_index: [usize; NDIM]) -> Option<&mut Self::Item>;
}
pub trait RawAccess: BaseItem {
fn data(&self) -> Option<&[Self::Item]>;
}
pub trait RawAccessMut: RawAccess {
fn data_mut(&mut self) -> Option<&mut [Self::Item]>;
}
pub unsafe trait StableRawAccessMut: RawAccessMut {}
#[inline]
fn check_dimension<const NDIM: usize>(multi_index: [usize; NDIM], shape: [usize; NDIM]) -> bool {
multi_index
.iter()
.zip(shape.iter())
.fold(true, |acc, (ind, s)| acc && (ind < s))
}
impl<Mat: UnsafeRandomAccessByValue<NDIM> + Shape<NDIM>, const NDIM: usize>
RandomAccessByValue<NDIM> for Mat
{
fn get_value(&self, multi_index: [usize; NDIM]) -> Option<Self::Item> {
if check_dimension(multi_index, self.shape()) {
Some(unsafe { self.get_value_unchecked(multi_index) })
} else {
None
}
}
}
impl<Item, Mat: UnsafeRandomAccessMut<NDIM, Item = Item> + Shape<NDIM>, const NDIM: usize>
RandomAccessMut<NDIM> for Mat
{
fn get_mut(&mut self, multi_index: [usize; NDIM]) -> Option<&mut Self::Item> {
if check_dimension(multi_index, self.shape()) {
unsafe { Some(self.get_unchecked_mut(multi_index)) }
} else {
None
}
}
}
impl<Item, Mat: UnsafeRandomAccessByRef<NDIM, Item = Item> + Shape<NDIM>, const NDIM: usize>
RandomAccessByRef<NDIM> for Mat
{
fn get(&self, multi_index: [usize; NDIM]) -> Option<&Self::Item> {
if check_dimension(multi_index, self.shape()) {
unsafe { Some(self.get_unchecked(multi_index)) }
} else {
None
}
}
}