mod private
{
use crate::{ Collection, ArrayRef };
use core::
{
fmt,
ops::{ Add, Mul },
cmp::PartialOrd,
};
pub trait DimOffset< const N : usize > : Collection
{
fn offset< V2 >( &self, md_index : &V2 ) -> Self::Scalar
where
V2 : ArrayRef< Self::Scalar, N > + Collection< Scalar = Self::Scalar > + fmt::Debug + ?Sized;
}
impl< E, V, const N : usize > DimOffset< N > for V
where
Self : Collection< Scalar = E > + fmt::Debug,
E : Mul< E, Output = E > + Add< E, Output = E > + PartialOrd + Copy + Default + From< u8 >,
V : ArrayRef< E, N > + Collection< Scalar = E > + fmt::Debug + ?Sized,
{
#[ inline ]
fn offset< V2 >( &self, md_index : &V2 ) -> Self::Scalar
where
V2 : ArrayRef< E, N > + Collection< Scalar = Self::Scalar > + fmt::Debug + ?Sized,
{
let mut offset = E::default();
let mut stride = E::from( 1 ); for i in 0..N
{
let dim_index = N - 1 - i; debug_assert!
(
md_index.array_ref()[ dim_index ] < self.array_ref()[ dim_index ],
"md_index : {md_index:?} | md_size : {self:?}"
);
offset = offset + stride * md_index.array_ref()[ dim_index ];
stride = stride * self.array_ref()[ dim_index ];
}
offset
}
}
}
crate::mod_interface!
{
own use DimOffset;
}