add associated constructor to `Dimension` trait
jonasBoss opened this issue · comments
I am working on the ndarray-interp crate, which is generic over the number of dimensions. This causes difficulties when the I need to construct a Dimension that is bigger than 6 (IxDyn
).
Specifically the method interp_array
needs to generically construct its return array of Dimension <Dq as DimAdd<D::Smaller>>::Output where Dq: Dimension + DimAdd<D::Smaller>
.
This works fine for static dimensions as I can use the Default
trait to create the correct Dimension. But when <Dq as DimAdd<D::Smaller>>::Output
happens to be IxDyn
this does not work because the information about the number of dimensions is lost.
This is my current, very ugly solution:
let shape = match <Dq as DimAdd<D::Smaller>>::Output::NDIM {
Some(_) => {
let mut dim = <Dq as DimAdd<D::Smaller>>::Output::default();
dim.as_array_view_mut()
.into_iter()
// ... set the correct axis lenghts
;
dim
}
None => {
let lenghts: Vec<usize> = ; // ... collect the correct axis lenghts
let dyn_dim = IxDyn(&lenghts);
(&dyn_dim as &dyn Any)
.downcast_ref::<<Dq as DimAdd<D::Smaller>>::Output>()
.unwrap_or_else(|| unimplemented!())
.clone()
}
};
This requires ndarray
to guarantee that Dimension::NDIM
is only ever None
when the underlying type is IxDyn
. If there is ever a impl Dimension for NewType
this code will probably brake.
I might have missed something, but there does not seem to be a good solution for this problem currently.
I suggest extending the Dimenion trait, possibly by requiring Dimension: TryFrom<&[Ix]>
or adding a associated constructor:
trait Dimension {
/// try to create a new Dimension from the provided slice
/// fails when `Self::NDIM.is_some_and(|ndim| ndim != ix.len())`
fn try_new(ix: &[Ix]) -> Option<Self>;
}