use super::memory::NumericArrayResizable;
use super::{LVArray, LVArrayHandle};
use crate::errors::Result;
use ndarray::{ArrayView, ArrayViewMut, Dim, Ix};
macro_rules! array_with_dim {
($dim:literal) => {
impl<T> LVArray<$dim, T> {
fn ndarray_dim(&self) -> Dim<[Ix; $dim]> {
let sizes: [Ix; $dim] = self.dim_sizes.into();
Dim(sizes)
}
pub fn ndarray_view(&self) -> ArrayView<T, Dim<[Ix; $dim]>> {
let dim_sizes = self.ndarray_dim();
let data = self.data_as_slice();
ArrayView::from_shape(dim_sizes, data).unwrap()
}
pub fn ndarray_view_mut(&mut self) -> ArrayViewMut<T, Dim<[Ix; $dim]>> {
let dim_sizes = self.ndarray_dim();
let data = self.data_as_slice_mut();
ArrayViewMut::from_shape(dim_sizes, data).unwrap()
}
}
impl<'array, T: Copy + NumericArrayResizable + 'array> LVArrayHandle<'array, $dim, T> {
pub fn copy_from_ndarray<'a>(
&mut self,
array: impl Into<ArrayView<'a, T, Dim<[Ix; $dim]>>>,
) -> Result<()>
where
T: 'a,
{
self.copy_from_ndarray_view(array.into())
}
fn copy_from_ndarray_view<'a>(
&mut self,
array: ArrayView<'a, T, Dim<[Ix; $dim]>>,
) -> Result<()>
where
T: 'a,
{
if array.raw_dim() != self.ndarray_dim() {
#[cfg(feature = "link")]
{
self.resize_array(array.shape().try_into()?)?;
}
#[cfg(not(feature = "link"))]
{
return Err(LVInteropError::ArrayDimensionMismatch);
}
}
let lv_array = unsafe { self.as_ref_mut()? };
for (output, input) in lv_array.data_as_slice_mut().iter_mut().zip(array.iter()) {
*output = *input
}
Ok(())
}
}
};
}
array_with_dim!(1);
array_with_dim!(2);
array_with_dim!(3);
array_with_dim!(4);
array_with_dim!(5);
array_with_dim!(6);