Skip to content

Commit 716600e

Browse files
committed
Switch from Dimension::SliceArg to CanSlice trait
1 parent d45eeb9 commit 716600e

File tree

7 files changed

+252
-141
lines changed

7 files changed

+252
-141
lines changed

src/dimension/dimension_trait.rs

+1-22
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::ops::{Add, Sub, Mul, AddAssign, SubAssign, MulAssign};
1313

1414
use itertools::{enumerate, izip, zip};
1515

16-
use {Ix, Ixs, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, Dim, AxisSliceInfo, IxDynImpl};
16+
use {Ix, Ixs, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, Dim, IxDynImpl};
1717
use IntoDimension;
1818
use RemoveAxis;
1919
use {ArrayView1, ArrayViewMut1};
@@ -45,21 +45,6 @@ pub trait Dimension : Clone + Eq + Debug + Send + Sync + Default +
4545
/// `Some(ndim)`, and for variable-size dimension representations (e.g.
4646
/// `IxDyn`), this should be `None`.
4747
const NDIM: Option<usize>;
48-
/// `SliceArg` is the type which is used to specify slicing for this
49-
/// dimension.
50-
///
51-
/// For the fixed size dimensions it is a fixed size array of the correct
52-
/// size, which you pass by reference. For the dynamic dimension it is
53-
/// a slice.
54-
///
55-
/// - For `Ix1`: `[AxisSliceInfo; 1]`
56-
/// - For `Ix2`: `[AxisSliceInfo; 2]`
57-
/// - and so on..
58-
/// - For `IxDyn`: `[AxisSliceInfo]`
59-
///
60-
/// The easiest way to create a `&SliceInfo<SliceArg, Do>` is using the
61-
/// [`s![]`](macro.s!.html) macro.
62-
type SliceArg: ?Sized + AsRef<[AxisSliceInfo]>;
6348
/// Pattern matching friendly form of the dimension value.
6449
///
6550
/// - For `Ix1`: `usize`,
@@ -364,7 +349,6 @@ macro_rules! impl_insert_axis_array(
364349

365350
impl Dimension for Dim<[Ix; 0]> {
366351
const NDIM: Option<usize> = Some(0);
367-
type SliceArg = [AxisSliceInfo; 0];
368352
type Pattern = ();
369353
type Smaller = Self;
370354
type Larger = Ix1;
@@ -401,7 +385,6 @@ impl Dimension for Dim<[Ix; 0]> {
401385

402386
impl Dimension for Dim<[Ix; 1]> {
403387
const NDIM: Option<usize> = Some(1);
404-
type SliceArg = [AxisSliceInfo; 1];
405388
type Pattern = Ix;
406389
type Smaller = Ix0;
407390
type Larger = Ix2;
@@ -499,7 +482,6 @@ impl Dimension for Dim<[Ix; 1]> {
499482

500483
impl Dimension for Dim<[Ix; 2]> {
501484
const NDIM: Option<usize> = Some(2);
502-
type SliceArg = [AxisSliceInfo; 2];
503485
type Pattern = (Ix, Ix);
504486
type Smaller = Ix1;
505487
type Larger = Ix3;
@@ -645,7 +627,6 @@ impl Dimension for Dim<[Ix; 2]> {
645627

646628
impl Dimension for Dim<[Ix; 3]> {
647629
const NDIM: Option<usize> = Some(3);
648-
type SliceArg = [AxisSliceInfo; 3];
649630
type Pattern = (Ix, Ix, Ix);
650631
type Smaller = Ix2;
651632
type Larger = Ix4;
@@ -763,7 +744,6 @@ macro_rules! large_dim {
763744
($n:expr, $name:ident, $pattern:ty, $larger:ty, { $($insert_axis:tt)* }) => (
764745
impl Dimension for Dim<[Ix; $n]> {
765746
const NDIM: Option<usize> = Some($n);
766-
type SliceArg = [AxisSliceInfo; $n];
767747
type Pattern = $pattern;
768748
type Smaller = Dim<[Ix; $n - 1]>;
769749
type Larger = $larger;
@@ -815,7 +795,6 @@ large_dim!(6, Ix6, (Ix, Ix, Ix, Ix, Ix, Ix), IxDyn, {
815795
impl Dimension for IxDyn
816796
{
817797
const NDIM: Option<usize> = None;
818-
type SliceArg = [AxisSliceInfo];
819798
type Pattern = Self;
820799
type Smaller = Self;
821800
type Larger = Self;

src/dimension/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
use {AxisSliceInfo, Ix, Ixs, Slice};
1010
use error::{from_kind, ErrorKind, ShapeError};
11+
use slice::CanSlice;
1112
use itertools::izip;
1213
use num_integer::div_floor;
1314

@@ -529,10 +530,10 @@ fn slice_min_max(axis_len: usize, slice: Slice) -> Option<(usize, usize)> {
529530
#[doc(hidden)]
530531
pub fn slices_intersect<D: Dimension>(
531532
dim: &D,
532-
indices1: &D::SliceArg,
533-
indices2: &D::SliceArg,
533+
indices1: &impl CanSlice<D>,
534+
indices2: &impl CanSlice<D>,
534535
) -> bool {
535-
debug_assert_eq!(indices1.as_ref().len(), indices2.as_ref().len());
536+
debug_assert_eq!(indices1.in_ndim(), indices2.in_ndim());
536537
for (&axis_len, &si1, &si2) in izip!(dim.slice(), indices1.as_ref(), indices2.as_ref()) {
537538
// The slices do not intersect iff any pair of `AxisSliceInfo` does not intersect.
538539
match (si1, si2) {

src/impl_methods.rs

+46-37
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use {
2525
AxisSliceInfo,
2626
NdIndex,
2727
Slice,
28-
SliceInfo,
2928
};
3029
use iter::{
3130
AxisChunksIter,
@@ -42,6 +41,7 @@ use iter::{
4241
ExactChunksMut,
4342
Windows
4443
};
44+
use slice::CanSlice;
4545
use stacking::stack;
4646

4747
/// # Methods For All Array Types
@@ -303,9 +303,9 @@ where
303303
///
304304
/// **Panics** if an index is out of bounds or step size is zero.<br>
305305
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
306-
pub fn slice<Do>(&self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayView<A, Do>
306+
pub fn slice<I>(&self, info: &I) -> ArrayView<A, I::OutDim>
307307
where
308-
Do: Dimension,
308+
I: CanSlice<D>,
309309
S: Data,
310310
{
311311
self.view().slice_move(info)
@@ -321,9 +321,9 @@ where
321321
///
322322
/// **Panics** if an index is out of bounds or step size is zero.<br>
323323
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
324-
pub fn slice_mut<Do>(&mut self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayViewMut<A, Do>
324+
pub fn slice_mut<I>(&mut self, info: &I) -> ArrayViewMut<A, I::OutDim>
325325
where
326-
Do: Dimension,
326+
I: CanSlice<D>,
327327
S: DataMut,
328328
{
329329
self.view_mut().slice_move(info)
@@ -339,29 +339,37 @@ 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_move<Do>(mut self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayBase<S, Do>
342+
pub fn slice_move<I>(mut self, info: &I) -> ArrayBase<S, I::OutDim>
343343
where
344-
Do: Dimension,
344+
I: CanSlice<D>,
345345
{
346346
// Slice and collapse in-place without changing the number of dimensions.
347-
self.slice_collapse(&*info);
347+
self.slice_collapse(info);
348348

349-
let indices: &[AxisSliceInfo] = (**info).as_ref();
350-
351-
// Copy the dim and strides that remain after removing the subview axes.
352349
let out_ndim = info.out_ndim();
353-
let mut new_dim = Do::zeros(out_ndim);
354-
let mut new_strides = Do::zeros(out_ndim);
355-
izip!(self.dim.slice(), self.strides.slice(), indices)
356-
.filter_map(|(d, s, slice_or_index)| match slice_or_index {
357-
&AxisSliceInfo::Slice {..} => Some((d, s)),
358-
&AxisSliceInfo::Index(_) => None,
359-
})
360-
.zip(izip!(new_dim.slice_mut(), new_strides.slice_mut()))
361-
.for_each(|((d, s), (new_d, new_s))| {
362-
*new_d = *d;
363-
*new_s = *s;
350+
let mut new_dim = I::OutDim::zeros(out_ndim);
351+
let mut new_strides = I::OutDim::zeros(out_ndim);
352+
353+
// Write the dim and strides to the correct new axes.
354+
{
355+
let mut old_axis = 0;
356+
let mut new_axis = 0;
357+
info.as_ref().iter().for_each(|ax_info| match ax_info {
358+
&AxisSliceInfo::Slice { .. } => {
359+
// Copy the old dim and stride to corresponding axis.
360+
new_dim[new_axis] = self.dim[old_axis];
361+
new_strides[new_axis] = self.strides[old_axis];
362+
old_axis += 1;
363+
new_axis += 1;
364+
}
365+
&AxisSliceInfo::Index(_) => {
366+
// Skip the old axis since it should be removed.
367+
old_axis += 1;
368+
}
364369
});
370+
debug_assert_eq!(old_axis, self.ndim());
371+
debug_assert_eq!(new_axis, out_ndim);
372+
}
365373

366374
ArrayBase {
367375
ptr: self.ptr,
@@ -373,25 +381,23 @@ where
373381

374382
/// Slice the array in place without changing the number of dimensions.
375383
///
376-
/// Note that [`&SliceInfo`](struct.SliceInfo.html) (produced by the
377-
/// [`s![]`](macro.s!.html) macro) will usually coerce into `&D::SliceArg`
378-
/// automatically, but in some cases (e.g. if `D` is `IxDyn`), you may need
379-
/// to call `.as_ref()`.
380-
///
381384
/// See [*Slicing*](#slicing) for full documentation.
382-
/// See also [`D::SliceArg`].
383-
///
384-
/// [`D::SliceArg`]: trait.Dimension.html#associatedtype.SliceArg
385385
///
386386
/// **Panics** if an index is out of bounds or step size is zero.<br>
387-
/// (**Panics** if `D` is `IxDyn` and `indices` does not match the number of array axes.)
388-
pub fn slice_collapse(&mut self, indices: &D::SliceArg) {
389-
let indices: &[AxisSliceInfo] = indices.as_ref();
390-
assert_eq!(indices.len(), self.ndim());
391-
indices
387+
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
388+
pub fn slice_collapse<I>(&mut self, info: &I)
389+
where
390+
I: CanSlice<D>,
391+
{
392+
assert_eq!(
393+
info.in_ndim(),
394+
self.ndim(),
395+
"The input dimension of `info` must match the array to be sliced.",
396+
);
397+
info.as_ref()
392398
.iter()
393399
.enumerate()
394-
.for_each(|(axis, slice_or_index)| match slice_or_index {
400+
.for_each(|(axis, ax_info)| match ax_info {
395401
&AxisSliceInfo::Slice { start, end, step } => {
396402
self.slice_axis_inplace(Axis(axis), Slice { start, end, step })
397403
}
@@ -407,7 +413,10 @@ where
407413
/// **Panics** if an index is out of bounds or step size is zero.<br>
408414
/// (**Panics** if `D` is `IxDyn` and `indices` does not match the number of array axes.)
409415
#[deprecated(note="renamed to `slice_collapse`", since="0.12.1")]
410-
pub fn slice_inplace(&mut self, indices: &D::SliceArg) {
416+
pub fn slice_inplace<I>(&mut self, indices: &I)
417+
where
418+
I: CanSlice<D>,
419+
{
411420
self.slice_collapse(indices)
412421
}
413422

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ pub use indexes::{indices, indices_of};
127127
pub use error::{ShapeError, ErrorKind};
128128
pub use slice::{
129129
deref_raw_view_mut_into_view_with_life, deref_raw_view_mut_into_view_mut_with_life,
130-
life_of_view_mut, AxisSliceInfo, Slice, SliceInfo, SliceNextDim,
130+
life_of_view_mut, AxisSliceInfo, Slice, SliceInfo, SliceNextInDim, SliceNextOutDim,
131131
};
132132

133133
use iterators::Baseiter;

0 commit comments

Comments
 (0)