diff --git a/src/lib.rs b/src/lib.rs index 6ca1ed75d..c1b041d53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,7 +140,7 @@ pub use crate::dimension::IxDynImpl; pub use crate::dimension::NdIndex; pub use crate::error::{ErrorKind, ShapeError}; pub use crate::indexes::{indices, indices_of}; -pub use crate::slice::{AxisSliceInfo, NewAxis, Slice, SliceInfo, SliceNextInDim, SliceNextOutDim}; +pub use crate::slice::{AxisSliceInfo, NewAxis, Slice, SliceArg, SliceInfo}; use crate::iterators::Baseiter; use crate::iterators::{ElementsBase, ElementsBaseMut, Iter, IterMut, Lanes, LanesMut}; diff --git a/src/slice.rs b/src/slice.rs index 24cbafda2..d19a889e9 100644 --- a/src/slice.rs +++ b/src/slice.rs @@ -7,10 +7,10 @@ // except according to those terms. use crate::dimension::slices_intersect; use crate::error::{ErrorKind, ShapeError}; +use crate::{ArrayViewMut, DimAdd, Dimension, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn}; use std::fmt; use std::marker::PhantomData; use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; -use crate::{ArrayViewMut, Dimension, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn}; /// A slice (range with step size). /// @@ -536,72 +536,51 @@ where } } +/// Trait for determining dimensionality of input and output for [`s!`] macro. #[doc(hidden)] -pub trait SliceNextInDim { - fn next_dim(&self, _: PhantomData) -> PhantomData; -} +pub trait SliceArg { + /// Number of dimensions that this slicing argument consumes in the input array. + type InDim: Dimension; + /// Number of dimensions that this slicing argument produces in the output array. + type OutDim: Dimension; -impl SliceNextInDim for NewAxis { - fn next_dim(&self, _: PhantomData) -> PhantomData { + fn next_in_dim(&self, _: PhantomData) -> PhantomData + where + D: Dimension + DimAdd, + { PhantomData } -} -macro_rules! impl_slicenextindim_larger { - (($($generics:tt)*), $self:ty) => { - impl SliceNextInDim for $self { - fn next_dim(&self, _: PhantomData) -> PhantomData { - PhantomData - } - } + fn next_out_dim(&self, _: PhantomData) -> PhantomData + where + D: Dimension + DimAdd, + { + PhantomData } } -impl_slicenextindim_larger!((), isize); -impl_slicenextindim_larger!((), usize); -impl_slicenextindim_larger!((), i32); -impl_slicenextindim_larger!((T), Range); -impl_slicenextindim_larger!((T), RangeInclusive); -impl_slicenextindim_larger!((T), RangeFrom); -impl_slicenextindim_larger!((T), RangeTo); -impl_slicenextindim_larger!((T), RangeToInclusive); -impl_slicenextindim_larger!((), RangeFull); -impl_slicenextindim_larger!((), Slice); - -#[doc(hidden)] -pub trait SliceNextOutDim { - fn next_dim(&self, _: PhantomData) -> PhantomData; -} -macro_rules! impl_slicenextoutdim_equal { - ($self:ty) => { - impl SliceNextOutDim for $self { - fn next_dim(&self, _: PhantomData) -> PhantomData { - PhantomData - } +macro_rules! impl_slicearg { + (($($generics:tt)*), $self:ty, $in:ty, $out:ty) => { + impl<$($generics)*> SliceArg for $self { + type InDim = $in; + type OutDim = $out; } }; } -impl_slicenextoutdim_equal!(isize); -impl_slicenextoutdim_equal!(usize); -impl_slicenextoutdim_equal!(i32); - -macro_rules! impl_slicenextoutdim_larger { - (($($generics:tt)*), $self:ty) => { - impl SliceNextOutDim for $self { - fn next_dim(&self, _: PhantomData) -> PhantomData { - PhantomData - } - } - } -} -impl_slicenextoutdim_larger!((T), Range); -impl_slicenextoutdim_larger!((T), RangeInclusive); -impl_slicenextoutdim_larger!((T), RangeFrom); -impl_slicenextoutdim_larger!((T), RangeTo); -impl_slicenextoutdim_larger!((T), RangeToInclusive); -impl_slicenextoutdim_larger!((), RangeFull); -impl_slicenextoutdim_larger!((), Slice); -impl_slicenextoutdim_larger!((), NewAxis); + +impl_slicearg!((), isize, Ix1, Ix0); +impl_slicearg!((), usize, Ix1, Ix0); +impl_slicearg!((), i32, Ix1, Ix0); + +impl_slicearg!((T), Range, Ix1, Ix1); +impl_slicearg!((T), RangeInclusive, Ix1, Ix1); +impl_slicearg!((T), RangeFrom, Ix1, Ix1); +impl_slicearg!((T), RangeTo, Ix1, Ix1); +impl_slicearg!((T), RangeToInclusive, Ix1, Ix1); +impl_slicearg!((), RangeFull, Ix1, Ix1); +impl_slicearg!((), Slice, Ix1, Ix1); + +impl_slicearg!((), NewAxis, Ix0, Ix1); /// Slice argument constructor. /// @@ -703,8 +682,8 @@ macro_rules! s( (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr;$s:expr) => { match $r { r => { - let in_dim = $crate::SliceNextInDim::next_dim(&r, $in_dim); - let out_dim = $crate::SliceNextOutDim::next_dim(&r, $out_dim); + let in_dim = $crate::SliceArg::next_in_dim(&r, $in_dim); + let out_dim = $crate::SliceArg::next_out_dim(&r, $out_dim); #[allow(unsafe_code)] unsafe { $crate::SliceInfo::new_unchecked( @@ -720,8 +699,8 @@ macro_rules! s( (@parse $in_dim:expr, $out_dim:expr, [$($stack:tt)*] $r:expr) => { match $r { r => { - let in_dim = $crate::SliceNextInDim::next_dim(&r, $in_dim); - let out_dim = $crate::SliceNextOutDim::next_dim(&r, $out_dim); + let in_dim = $crate::SliceArg::next_in_dim(&r, $in_dim); + let out_dim = $crate::SliceArg::next_out_dim(&r, $out_dim); #[allow(unsafe_code)] unsafe { $crate::SliceInfo::new_unchecked( @@ -746,8 +725,8 @@ macro_rules! s( match $r { r => { $crate::s![@parse - $crate::SliceNextInDim::next_dim(&r, $in_dim), - $crate::SliceNextOutDim::next_dim(&r, $out_dim), + $crate::SliceArg::next_in_dim(&r, $in_dim), + $crate::SliceArg::next_out_dim(&r, $out_dim), [$($stack)* $crate::s!(@convert r, $s),] $($t)* ] @@ -759,8 +738,8 @@ macro_rules! s( match $r { r => { $crate::s![@parse - $crate::SliceNextInDim::next_dim(&r, $in_dim), - $crate::SliceNextOutDim::next_dim(&r, $out_dim), + $crate::SliceArg::next_in_dim(&r, $in_dim), + $crate::SliceArg::next_out_dim(&r, $out_dim), [$($stack)* $crate::s!(@convert r),] $($t)* ]