Skip to content

Commit 4ada8b9

Browse files
authored
feat: add Dimension::from_slice (#1608)
Add a public `from_slice` that returns `None` when the slice length does not match the type's dimensionality (`IxDyn` accepts any length). Now `from_dimension` uses `from_slice`. Closes #1330
1 parent 34d4e13 commit 4ada8b9

2 files changed

Lines changed: 36 additions & 21 deletions

File tree

‎src/dimension/dimension_trait.rs‎

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -375,18 +375,24 @@ pub trait Dimension:
375375
IxDyn(self.slice())
376376
}
377377

378+
/// Creates a dimension of this type from a slice of axis lengths.
379+
///
380+
/// Returns `None` if the slice length is incompatible with this
381+
/// dimension type's dimensionality
382+
fn from_slice(ix: &[Ix]) -> Option<Self>
383+
{
384+
if Self::NDIM.is_some_and(|n| n != ix.len()) {
385+
return None;
386+
}
387+
let mut s = Self::zeros(ix.len());
388+
s.slice_mut().copy_from_slice(ix);
389+
Some(s)
390+
}
391+
378392
#[doc(hidden)]
379393
fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self>
380394
{
381-
let mut s = Self::default();
382-
if s.ndim() == d.ndim() {
383-
for i in 0..d.ndim() {
384-
s[i] = d[i];
385-
}
386-
Some(s)
387-
} else {
388-
None
389-
}
395+
Self::from_slice(d.slice())
390396
}
391397

392398
#[doc(hidden)]
@@ -584,15 +590,6 @@ impl Dimension for Dim<[Ix; 1]>
584590
{
585591
self.remove_axis(axis)
586592
}
587-
588-
fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self>
589-
{
590-
if 1 == d.ndim() {
591-
Some(Ix1(d[0]))
592-
} else {
593-
None
594-
}
595-
}
596593
private_impl! {}
597594
}
598595

@@ -1003,9 +1000,9 @@ impl Dimension for IxDyn
10031000
}
10041001
}
10051002

1006-
fn from_dimension<D2: Dimension>(d: &D2) -> Option<Self>
1003+
fn from_slice(ix: &[Ix]) -> Option<Self>
10071004
{
1008-
Some(IxDyn(d.slice()))
1005+
Some(IxDyn(ix))
10091006
}
10101007

10111008
fn into_dyn(self) -> IxDyn

‎tests/dimension.rs‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use defmac::defmac;
44

5-
use ndarray::{arr2, ArcArray, Array, Axis, Dim, Dimension, IxDyn, RemoveAxis};
5+
use ndarray::{arr2, ArcArray, Array, Axis, Dim, Dimension, Ix0, Ix2, IxDyn, RemoveAxis};
66

77
use std::hash::{Hash, Hasher};
88

@@ -360,3 +360,21 @@ fn test_all_ndindex()
360360
ndindex!(10, 4, 3, 2, 2);
361361
ndindex!(10, 4, 3, 2, 2, 2);
362362
}
363+
364+
#[test]
365+
fn from_slice()
366+
{
367+
assert_eq!(Ix0::from_slice(&[]), Some(Dim([])));
368+
assert_eq!(Ix0::from_slice(&[1]), None);
369+
370+
assert_eq!(Ix2::from_slice(&[2, 3]), Some(Dim([2, 3])));
371+
assert_eq!(Ix2::from_slice(&[2]), None);
372+
assert_eq!(Ix2::from_slice(&[2, 3, 4]), None);
373+
374+
assert_eq!(IxDyn::from_slice(&[]), Some(IxDyn(&[])));
375+
assert_eq!(IxDyn::from_slice(&[2, 3, 4, 5]), Some(IxDyn(&[2, 3, 4, 5])));
376+
377+
assert_eq!(Ix2::from_dimension(&IxDyn(&[2, 3])), Some(Dim([2, 3])));
378+
assert_eq!(Ix2::from_dimension(&IxDyn(&[2, 3, 4])), None);
379+
assert_eq!(IxDyn::from_dimension(&Dim([2, 3])), Some(IxDyn(&[2, 3])));
380+
}

0 commit comments

Comments
 (0)