use super::validation;
use crate::error::{CoreError, ErrorContext, ErrorLocation};
use ::ndarray::{
Array, ArrayBase, ArrayView as NdArrayView, ArrayViewMut as NdArrayViewMut, Data, Dimension,
Ix1, Ix2,
};
pub type ArrayView<'a, A, D> = NdArrayView<'a, A, D>;
pub type ViewMut<'a, A, D> = NdArrayViewMut<'a, A, D>;
pub unsafe fn view_as<A, B, S, D>(array: &ArrayBase<S, D>) -> Result<ArrayView<'_, B, D>, CoreError>
where
A: Clone,
S: Data<Elem = A>,
D: Dimension,
{
validation::check_not_empty(array)?;
let a_size = std::mem::size_of::<A>();
let b_size = std::mem::size_of::<B>();
if a_size == 0 || b_size == 0 {
return Err(CoreError::ValidationError(
ErrorContext::new("Cannot reinterpret view of zero-sized type".to_string())
.with_location(ErrorLocation::new(file!(), line!())),
));
}
if a_size % b_size != 0 && b_size % a_size != 0 {
return Err(CoreError::ValidationError(
ErrorContext::new(format!(
"Type sizes are not compatible: {a_size} is not divisible by or a divisor of {b_size}"
))
.with_location(ErrorLocation::new(file!(), line!())),
));
}
Err(CoreError::ImplementationError(
ErrorContext::new("view_as is not yet implemented".to_string())
.with_location(ErrorLocation::new(file!(), line!())),
))
}
pub unsafe fn view_mut_as<A, B, S, D>(
array: &mut ArrayBase<S, D>,
) -> Result<ViewMut<'_, B, D>, CoreError>
where
A: Clone,
S: Data<Elem = A>,
D: Dimension,
{
validation::check_not_empty(array)?;
let a_size = std::mem::size_of::<A>();
let b_size = std::mem::size_of::<B>();
if a_size == 0 || b_size == 0 {
return Err(CoreError::ValidationError(
ErrorContext::new("Cannot reinterpret view of zero-sized type".to_string())
.with_location(ErrorLocation::new(file!(), line!())),
));
}
if a_size % b_size != 0 && b_size % a_size != 0 {
return Err(CoreError::ValidationError(
ErrorContext::new(format!(
"Type sizes are not compatible: {a_size} is not divisible by or a divisor of {b_size}"
))
.with_location(ErrorLocation::new(file!(), line!())),
));
}
Err(CoreError::ImplementationError(
ErrorContext::new("view_mut_as is not yet implemented".to_string())
.with_location(ErrorLocation::new(file!(), line!())),
))
}
#[allow(dead_code)]
pub fn transpose_view<A, S>(array: &ArrayBase<S, Ix2>) -> Result<Array<A, Ix2>, CoreError>
where
A: Clone,
S: Data<Elem = A>,
{
validation::check_not_empty(array)?;
Ok(array.to_owned().t().to_owned())
}
#[allow(dead_code)]
pub fn diagonal_view<A, S>(array: &ArrayBase<S, Ix2>) -> Result<Array<A, Ix1>, CoreError>
where
A: Clone,
S: Data<Elem = A>,
{
validation::check_not_empty(array)?;
validation::check_square(array)?;
Ok(array.diag().to_owned())
}