Skip to content

Commit 6a16b88

Browse files
jturner314bluss
authored andcommitted
Switch from Dimension::SliceArg to CanSlice trait
1 parent 24a3299 commit 6a16b88

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
@@ -432,7 +432,7 @@ fn scaled_add_3() {
432432

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

437437
let mut answerv = answer.slice_mut(s![..;s1, ..;s2]);
438438
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, DimMax};
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
///
@@ -56,21 +56,6 @@ pub trait Dimension:
5656
/// `Some(ndim)`, and for variable-size dimension representations (e.g.
5757
/// `IxDyn`), this should be `None`.
5858
const NDIM: Option<usize>;
59-
/// `SliceArg` is the type which is used to specify slicing for this
60-
/// dimension.
61-
///
62-
/// For the fixed size dimensions it is a fixed size array of the correct
63-
/// size, which you pass by reference. For the dynamic dimension it is
64-
/// a slice.
65-
///
66-
/// - For `Ix1`: `[AxisSliceInfo; 1]`
67-
/// - For `Ix2`: `[AxisSliceInfo; 2]`
68-
/// - and so on..
69-
/// - For `IxDyn`: `[AxisSliceInfo]`
70-
///
71-
/// The easiest way to create a `&SliceInfo<SliceArg, Do>` is using the
72-
/// [`s![]`](macro.s!.html) macro.
73-
type SliceArg: ?Sized + AsRef<[AxisSliceInfo]>;
7459
/// Pattern matching friendly form of the dimension value.
7560
///
7661
/// - For `Ix1`: `usize`,
@@ -399,7 +384,6 @@ macro_rules! impl_insert_axis_array(
399384

400385
impl Dimension for Dim<[Ix; 0]> {
401386
const NDIM: Option<usize> = Some(0);
402-
type SliceArg = [AxisSliceInfo; 0];
403387
type Pattern = ();
404388
type Smaller = Self;
405389
type Larger = Ix1;
@@ -443,7 +427,6 @@ impl Dimension for Dim<[Ix; 0]> {
443427

444428
impl Dimension for Dim<[Ix; 1]> {
445429
const NDIM: Option<usize> = Some(1);
446-
type SliceArg = [AxisSliceInfo; 1];
447430
type Pattern = Ix;
448431
type Smaller = Ix0;
449432
type Larger = Ix2;
@@ -559,7 +542,6 @@ impl Dimension for Dim<[Ix; 1]> {
559542

560543
impl Dimension for Dim<[Ix; 2]> {
561544
const NDIM: Option<usize> = Some(2);
562-
type SliceArg = [AxisSliceInfo; 2];
563545
type Pattern = (Ix, Ix);
564546
type Smaller = Ix1;
565547
type Larger = Ix3;
@@ -716,7 +698,6 @@ impl Dimension for Dim<[Ix; 2]> {
716698

717699
impl Dimension for Dim<[Ix; 3]> {
718700
const NDIM: Option<usize> = Some(3);
719-
type SliceArg = [AxisSliceInfo; 3];
720701
type Pattern = (Ix, Ix, Ix);
721702
type Smaller = Ix2;
722703
type Larger = Ix4;
@@ -839,7 +820,6 @@ macro_rules! large_dim {
839820
($n:expr, $name:ident, $pattern:ty, $larger:ty, { $($insert_axis:tt)* }) => (
840821
impl Dimension for Dim<[Ix; $n]> {
841822
const NDIM: Option<usize> = Some($n);
842-
type SliceArg = [AxisSliceInfo; $n];
843823
type Pattern = $pattern;
844824
type Smaller = Dim<[Ix; $n - 1]>;
845825
type Larger = $larger;
@@ -890,7 +870,6 @@ large_dim!(6, Ix6, (Ix, Ix, Ix, Ix, Ix, Ix), IxDyn, {
890870
/// and memory wasteful, but it allows an arbitrary and dynamic number of axes.
891871
impl Dimension for IxDyn {
892872
const NDIM: Option<usize> = None;
893-
type SliceArg = [AxisSliceInfo];
894873
type Pattern = Self;
895874
type Smaller = Self;
896875
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

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

src/impl_methods.rs

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

3939
/// # Methods For All Array Types
4040
impl<A, S, D> ArrayBase<S, D>
@@ -341,9 +341,9 @@ where
341341
///
342342
/// **Panics** if an index is out of bounds or step size is zero.<br>
343343
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
344-
pub fn slice<Do>(&self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayView<'_, A, Do>
344+
pub fn slice<I>(&self, info: &I) -> ArrayView<'_, A, I::OutDim>
345345
where
346-
Do: Dimension,
346+
I: CanSlice<D>,
347347
S: Data,
348348
{
349349
self.view().slice_move(info)
@@ -359,9 +359,9 @@ where
359359
///
360360
/// **Panics** if an index is out of bounds or step size is zero.<br>
361361
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
362-
pub fn slice_mut<Do>(&mut self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayViewMut<'_, A, Do>
362+
pub fn slice_mut<I>(&mut self, info: &I) -> ArrayViewMut<'_, A, I::OutDim>
363363
where
364-
Do: Dimension,
364+
I: CanSlice<D>,
365365
S: DataMut,
366366
{
367367
self.view_mut().slice_move(info)
@@ -410,29 +410,37 @@ where
410410
///
411411
/// **Panics** if an index is out of bounds or step size is zero.<br>
412412
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
413-
pub fn slice_move<Do>(mut self, info: &SliceInfo<D::SliceArg, Do>) -> ArrayBase<S, Do>
413+
pub fn slice_move<I>(mut self, info: &I) -> ArrayBase<S, I::OutDim>
414414
where
415-
Do: Dimension,
415+
I: CanSlice<D>,
416416
{
417417
// Slice and collapse in-place without changing the number of dimensions.
418-
self.slice_collapse(&*info);
418+
self.slice_collapse(info);
419419

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

437445
// safe because new dimension, strides allow access to a subset of old data
438446
unsafe {
@@ -442,25 +450,23 @@ where
442450

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

src/lib.rs

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

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

0 commit comments

Comments
 (0)