@@ -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 } ;
3434use crate :: stacking:: concatenate;
35- use crate :: { AxisSliceInfo , NdIndex , Slice , SliceInfo } ;
35+ use crate :: { AxisSliceInfo , NdIndex , Slice } ;
3636
3737/// # Methods For All Array Types
3838impl < 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 }
0 commit comments