Skip to content

Commit 01c3d32

Browse files
committed
Switch from Dimension::SliceArg to CanSlice trait
1 parent 7e7777f commit 01c3d32

File tree

8 files changed

+273
-157
lines changed

8 files changed

+273
-157
lines changed

blas-tests/tests/oper.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ fn scaled_add_3() {
433433

434434
{
435435
let mut av = a.slice_mut(s![..;s1, ..;s2]);
436-
let c = c.slice(SliceInfo::<_, IxDyn>::new(cslice).unwrap().as_ref());
436+
let c = c.slice(&SliceInfo::<_, IxDyn, IxDyn>::new(cslice).unwrap());
437437

438438
let mut answerv = answer.slice_mut(s![..;s1, ..;s2]);
439439
answerv += &(beta * &c);

src/dimension/dimension_trait.rs

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::Axis;
1919
use crate::IntoDimension;
2020
use crate::RemoveAxis;
2121
use crate::{ArrayView1, ArrayViewMut1};
22-
use crate::{AxisSliceInfo, Dim, Ix, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, IxDynImpl, Ixs};
22+
use crate::{Dim, Ix, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, IxDynImpl, Ixs};
2323

2424
/// Array shape and index trait.
2525
///
@@ -51,21 +51,6 @@ pub trait Dimension:
5151
/// `Some(ndim)`, and for variable-size dimension representations (e.g.
5252
/// `IxDyn`), this should be `None`.
5353
const NDIM: Option<usize>;
54-
/// `SliceArg` is the type which is used to specify slicing for this
55-
/// dimension.
56-
///
57-
/// For the fixed size dimensions it is a fixed size array of the correct
58-
/// size, which you pass by reference. For the dynamic dimension it is
59-
/// a slice.
60-
///
61-
/// - For `Ix1`: `[AxisSliceInfo; 1]`
62-
/// - For `Ix2`: `[AxisSliceInfo; 2]`
63-
/// - and so on..
64-
/// - For `IxDyn`: `[AxisSliceInfo]`
65-
///
66-
/// The easiest way to create a `&SliceInfo<SliceArg, Do>` is using the
67-
/// [`s![]`](macro.s!.html) macro.
68-
type SliceArg: ?Sized + AsRef<[AxisSliceInfo]>;
6954
/// Pattern matching friendly form of the dimension value.
7055
///
7156
/// - For `Ix1`: `usize`,
@@ -394,7 +379,6 @@ macro_rules! impl_insert_axis_array(
394379

395380
impl Dimension for Dim<[Ix; 0]> {
396381
const NDIM: Option<usize> = Some(0);
397-
type SliceArg = [AxisSliceInfo; 0];
398382
type Pattern = ();
399383
type Smaller = Self;
400384
type Larger = Ix1;
@@ -438,7 +422,6 @@ impl Dimension for Dim<[Ix; 0]> {
438422

439423
impl Dimension for Dim<[Ix; 1]> {
440424
const NDIM: Option<usize> = Some(1);
441-
type SliceArg = [AxisSliceInfo; 1];
442425
type Pattern = Ix;
443426
type Smaller = Ix0;
444427
type Larger = Ix2;
@@ -554,7 +537,6 @@ impl Dimension for Dim<[Ix; 1]> {
554537

555538
impl Dimension for Dim<[Ix; 2]> {
556539
const NDIM: Option<usize> = Some(2);
557-
type SliceArg = [AxisSliceInfo; 2];
558540
type Pattern = (Ix, Ix);
559541
type Smaller = Ix1;
560542
type Larger = Ix3;
@@ -711,7 +693,6 @@ impl Dimension for Dim<[Ix; 2]> {
711693

712694
impl Dimension for Dim<[Ix; 3]> {
713695
const NDIM: Option<usize> = Some(3);
714-
type SliceArg = [AxisSliceInfo; 3];
715696
type Pattern = (Ix, Ix, Ix);
716697
type Smaller = Ix2;
717698
type Larger = Ix4;
@@ -834,7 +815,6 @@ macro_rules! large_dim {
834815
($n:expr, $name:ident, $pattern:ty, $larger:ty, { $($insert_axis:tt)* }) => (
835816
impl Dimension for Dim<[Ix; $n]> {
836817
const NDIM: Option<usize> = Some($n);
837-
type SliceArg = [AxisSliceInfo; $n];
838818
type Pattern = $pattern;
839819
type Smaller = Dim<[Ix; $n - 1]>;
840820
type Larger = $larger;
@@ -885,7 +865,6 @@ large_dim!(6, Ix6, (Ix, Ix, Ix, Ix, Ix, Ix), IxDyn, {
885865
/// and memory wasteful, but it allows an arbitrary and dynamic number of axes.
886866
impl Dimension for IxDyn {
887867
const NDIM: Option<usize> = None;
888-
type SliceArg = [AxisSliceInfo];
889868
type Pattern = Self;
890869
type Smaller = Self;
891870
type Larger = Self;

src/dimension/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// except according to those terms.
88

99
use crate::error::{from_kind, ErrorKind, ShapeError};
10+
use crate::slice::CanSlice;
1011
use crate::{AxisSliceInfo, Ix, Ixs, Slice};
1112
use num_integer::div_floor;
1213

@@ -594,10 +595,10 @@ fn slice_min_max(axis_len: usize, slice: Slice) -> Option<(usize, usize)> {
594595
/// Returns `true` iff the slices intersect.
595596
pub fn slices_intersect<D: Dimension>(
596597
dim: &D,
597-
indices1: &D::SliceArg,
598-
indices2: &D::SliceArg,
598+
indices1: &impl CanSlice<D>,
599+
indices2: &impl CanSlice<D>,
599600
) -> bool {
600-
debug_assert_eq!(indices1.as_ref().len(), indices2.as_ref().len());
601+
debug_assert_eq!(indices1.in_ndim(), indices2.in_ndim());
601602
for (&axis_len, &si1, &si2) in izip!(dim.slice(), indices1.as_ref(), indices2.as_ref()) {
602603
// The slices do not intersect iff any pair of `AxisSliceInfo` does not intersect.
603604
match (si1, si2) {

src/impl_methods.rs

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ use crate::iter::{
3030
AxisChunksIter, AxisChunksIterMut, AxisIter, AxisIterMut, ExactChunks, ExactChunksMut,
3131
IndexedIter, IndexedIterMut, Iter, IterMut, Lanes, LanesMut, Windows,
3232
};
33-
use crate::slice::MultiSlice;
33+
use crate::slice::{CanSlice, MultiSlice};
3434
use crate::stacking::concatenate;
35-
use crate::{AxisSliceInfo, NdIndex, Slice, SliceInfo};
35+
use crate::{AxisSliceInfo, NdIndex, Slice};
3636

3737
/// # Methods For All Array Types
3838
impl<A, S, D> ArrayBase<S, D>
@@ -339,9 +339,9 @@ where
339339
///
340340
/// **Panics** if an index is out of bounds or step size is zero.<br>
341341
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
342-
pub fn slice<Do>(&self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayView<'_, A, Do>
342+
pub fn slice<I>(&self, info: &I) -> ArrayView<'_, A, I::OutDim>
343343
where
344-
Do: Dimension,
344+
I: CanSlice<D>,
345345
S: Data,
346346
{
347347
self.view().slice_move(info)
@@ -357,9 +357,9 @@ where
357357
///
358358
/// **Panics** if an index is out of bounds or step size is zero.<br>
359359
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
360-
pub fn slice_mut<Do>(&mut self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayViewMut<'_, A, Do>
360+
pub fn slice_mut<I>(&mut self, info: &I) -> ArrayViewMut<'_, A, I::OutDim>
361361
where
362-
Do: Dimension,
362+
I: CanSlice<D>,
363363
S: DataMut,
364364
{
365365
self.view_mut().slice_move(info)
@@ -408,29 +408,37 @@ where
408408
///
409409
/// **Panics** if an index is out of bounds or step size is zero.<br>
410410
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
411-
pub fn slice_move<Do>(mut self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayBase<S, Do>
411+
pub fn slice_move<I>(mut self, info: &I) -> ArrayBase<S, I::OutDim>
412412
where
413-
Do: Dimension,
413+
I: CanSlice<D>,
414414
{
415415
// Slice and collapse in-place without changing the number of dimensions.
416-
self.slice_collapse(&*info);
416+
self.slice_collapse(info);
417417

418-
let indices: &[AxisSliceInfo] = (**info).as_ref();
419-
420-
// Copy the dim and strides that remain after removing the subview axes.
421418
let out_ndim = info.out_ndim();
422-
let mut new_dim = Do::zeros(out_ndim);
423-
let mut new_strides = Do::zeros(out_ndim);
424-
izip!(self.dim.slice(), self.strides.slice(), indices)
425-
.filter_map(|(d, s, slice_or_index)| match slice_or_index {
426-
AxisSliceInfo::Slice { .. } => Some((d, s)),
427-
AxisSliceInfo::Index(_) => None,
428-
})
429-
.zip(izip!(new_dim.slice_mut(), new_strides.slice_mut()))
430-
.for_each(|((d, s), (new_d, new_s))| {
431-
*new_d = *d;
432-
*new_s = *s;
419+
let mut new_dim = I::OutDim::zeros(out_ndim);
420+
let mut new_strides = I::OutDim::zeros(out_ndim);
421+
422+
// Write the dim and strides to the correct new axes.
423+
{
424+
let mut old_axis = 0;
425+
let mut new_axis = 0;
426+
info.as_ref().iter().for_each(|ax_info| match ax_info {
427+
AxisSliceInfo::Slice { .. } => {
428+
// Copy the old dim and stride to corresponding axis.
429+
new_dim[new_axis] = self.dim[old_axis];
430+
new_strides[new_axis] = self.strides[old_axis];
431+
old_axis += 1;
432+
new_axis += 1;
433+
}
434+
AxisSliceInfo::Index(_) => {
435+
// Skip the old axis since it should be removed.
436+
old_axis += 1;
437+
}
433438
});
439+
debug_assert_eq!(old_axis, self.ndim());
440+
debug_assert_eq!(new_axis, out_ndim);
441+
}
434442

435443
// safe because new dimension, strides allow access to a subset of old data
436444
unsafe {
@@ -440,25 +448,23 @@ where
440448

441449
/// Slice the array in place without changing the number of dimensions.
442450
///
443-
/// Note that [`&SliceInfo`](struct.SliceInfo.html) (produced by the
444-
/// [`s![]`](macro.s!.html) macro) will usually coerce into `&D::SliceArg`
445-
/// automatically, but in some cases (e.g. if `D` is `IxDyn`), you may need
446-
/// to call `.as_ref()`.
447-
///
448451
/// See [*Slicing*](#slicing) for full documentation.
449-
/// See also [`D::SliceArg`].
450-
///
451-
/// [`D::SliceArg`]: trait.Dimension.html#associatedtype.SliceArg
452452
///
453453
/// **Panics** if an index is out of bounds or step size is zero.<br>
454-
/// (**Panics** if `D` is `IxDyn` and `indices` does not match the number of array axes.)
455-
pub fn slice_collapse(&mut self, indices: &D::SliceArg) {
456-
let indices: &[AxisSliceInfo] = indices.as_ref();
457-
assert_eq!(indices.len(), self.ndim());
458-
indices
454+
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
455+
pub fn slice_collapse<I>(&mut self, info: &I)
456+
where
457+
I: CanSlice<D>,
458+
{
459+
assert_eq!(
460+
info.in_ndim(),
461+
self.ndim(),
462+
"The input dimension of `info` must match the array to be sliced.",
463+
);
464+
info.as_ref()
459465
.iter()
460466
.enumerate()
461-
.for_each(|(axis, &slice_or_index)| match slice_or_index {
467+
.for_each(|(axis, &ax_info)| match ax_info {
462468
AxisSliceInfo::Slice { start, end, step } => {
463469
self.slice_axis_inplace(Axis(axis), Slice { start, end, step })
464470
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub use crate::dimension::IxDynImpl;
140140
pub use crate::dimension::NdIndex;
141141
pub use crate::error::{ErrorKind, ShapeError};
142142
pub use crate::indexes::{indices, indices_of};
143-
pub use crate::slice::{AxisSliceInfo, Slice, SliceInfo, SliceNextDim};
143+
pub use crate::slice::{AxisSliceInfo, Slice, SliceInfo, SliceNextInDim, SliceNextOutDim};
144144

145145
use crate::iterators::Baseiter;
146146
use crate::iterators::{ElementsBase, ElementsBaseMut, Iter, IterMut, Lanes, LanesMut};

0 commit comments

Comments
 (0)