use crate::{ArrayIndexer, ArrayStrideIter, Local, Stride};
use building_blocks_core::prelude::*;
#[derive(Clone)]
pub struct ArrayForEach<N> {
pub(crate) iter_extent: ExtentN<N>,
pub(crate) iter: ArrayStrideIter,
}
pub type Array2ForEach = ArrayForEach<[i32; 2]>;
pub type Array3ForEach = ArrayForEach<[i32; 3]>;
impl<N> ArrayForEach<N>
where
N: ArrayIndexer<N>,
PointN<N>: IntegerPoint<N>,
{
#[inline]
pub fn new_local_unchecked(
array_shape: PointN<N>,
origin: Local<N>,
iter_extent: ExtentN<N>,
) -> Self {
Self {
iter_extent,
iter: N::make_stride_iter(array_shape, origin, PointN::ONES),
}
}
#[inline]
pub fn new_local(array_shape: PointN<N>, iter_extent: ExtentN<N>) -> Self {
let iter_extent =
iter_extent.intersection(&ExtentN::from_min_and_shape(PointN::ZERO, array_shape));
Self::new_local_unchecked(array_shape, Local(iter_extent.minimum), iter_extent)
}
#[inline]
pub fn new_global_unchecked(array_extent: ExtentN<N>, iter_extent: ExtentN<N>) -> Self {
let origin = Local(iter_extent.minimum - array_extent.minimum);
Self {
iter_extent,
iter: N::make_stride_iter(array_extent.shape, origin, PointN::ONES),
}
}
#[inline]
pub fn new_global(array_extent: ExtentN<N>, iter_extent: ExtentN<N>) -> Self {
let iter_extent = iter_extent.intersection(&array_extent);
Self::new_global_unchecked(array_extent, iter_extent)
}
}
impl<N> ArrayForEach<N>
where
N: ArrayIndexer<N>,
{
pub fn for_each(self, f: impl FnMut(PointN<N>, Stride)) {
N::for_each(self, f)
}
}