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