@@ -30,9 +30,9 @@ use crate::iter::{
30
30
AxisChunksIter , AxisChunksIterMut , AxisIter , AxisIterMut , ExactChunks , ExactChunksMut ,
31
31
IndexedIter , IndexedIterMut , Iter , IterMut , Lanes , LanesMut , Windows ,
32
32
} ;
33
- use crate :: slice:: MultiSlice ;
33
+ use crate :: slice:: { CanSlice , MultiSlice } ;
34
34
use crate :: stacking:: concatenate;
35
- use crate :: { AxisSliceInfo , NdIndex , Slice , SliceInfo } ;
35
+ use crate :: { AxisSliceInfo , NdIndex , Slice } ;
36
36
37
37
/// # Methods For All Array Types
38
38
impl < A , S , D > ArrayBase < S , D >
@@ -339,9 +339,9 @@ where
339
339
///
340
340
/// **Panics** if an index is out of bounds or step size is zero.<br>
341
341
/// (**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 >
343
343
where
344
- Do : Dimension ,
344
+ I : CanSlice < D > ,
345
345
S : Data ,
346
346
{
347
347
self . view ( ) . slice_move ( info)
@@ -357,9 +357,9 @@ where
357
357
///
358
358
/// **Panics** if an index is out of bounds or step size is zero.<br>
359
359
/// (**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 >
361
361
where
362
- Do : Dimension ,
362
+ I : CanSlice < D > ,
363
363
S : DataMut ,
364
364
{
365
365
self . view_mut ( ) . slice_move ( info)
@@ -408,29 +408,37 @@ where
408
408
///
409
409
/// **Panics** if an index is out of bounds or step size is zero.<br>
410
410
/// (**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 >
412
412
where
413
- Do : Dimension ,
413
+ I : CanSlice < D > ,
414
414
{
415
415
// Slice and collapse in-place without changing the number of dimensions.
416
- self . slice_collapse ( & * info) ;
416
+ self . slice_collapse ( info) ;
417
417
418
- let indices: & [ AxisSliceInfo ] = ( * * info) . as_ref ( ) ;
419
-
420
- // Copy the dim and strides that remain after removing the subview axes.
421
418
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
+ }
433
438
} ) ;
439
+ debug_assert_eq ! ( old_axis, self . ndim( ) ) ;
440
+ debug_assert_eq ! ( new_axis, out_ndim) ;
441
+ }
434
442
435
443
// safe because new dimension, strides allow access to a subset of old data
436
444
unsafe {
@@ -440,25 +448,23 @@ where
440
448
441
449
/// Slice the array in place without changing the number of dimensions.
442
450
///
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
- ///
448
451
/// See [*Slicing*](#slicing) for full documentation.
449
- /// See also [`D::SliceArg`].
450
- ///
451
- /// [`D::SliceArg`]: trait.Dimension.html#associatedtype.SliceArg
452
452
///
453
453
/// **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 ( )
459
465
. iter ( )
460
466
. enumerate ( )
461
- . for_each ( |( axis, & slice_or_index ) | match slice_or_index {
467
+ . for_each ( |( axis, & ax_info ) | match ax_info {
462
468
AxisSliceInfo :: Slice { start, end, step } => {
463
469
self . slice_axis_inplace ( Axis ( axis) , Slice { start, end, step } )
464
470
}
0 commit comments