Skip to content

Commit 0759d12

Browse files
committed
Allow s!-style params in multislice! without s!
1 parent 88c689f commit 0759d12

File tree

3 files changed

+127
-23
lines changed

3 files changed

+127
-23
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ pub type Ixs = isize;
533533
/// // - One containing all the odd-index columns in the matrix
534534
/// let mut h = arr2(&[[0, 1, 2, 3],
535535
/// [4, 5, 6, 7]]);
536-
/// let (s0, s1) = multislice!(h, (mut s![.., ..;2], mut s![.., 1..;2]));
536+
/// let (s0, s1) = multislice!(h, (mut [.., ..;2], mut [.., 1..;2]));
537537
/// let i = arr2(&[[0, 2],
538538
/// [4, 6]]);
539539
/// let j = arr2(&[[1, 3],

src/slice.rs

Lines changed: 113 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -662,13 +662,15 @@ pub unsafe fn deref_raw_view_mut_into_view_mut_with_life<'a, A, D: Dimension>(
662662
/// disjoint).
663663
///
664664
/// The syntax is `multislice!(` *expression, (pattern [, pattern [, …]])* `)`,
665-
/// where *expression* evaluates to a mutable array, and `pattern` is one of
666-
/// the following:
665+
/// where *expression* evaluates to a mutable array, and each *pattern* is
666+
/// either
667667
///
668-
/// * `mut expr`: creates an `ArrayViewMut`, where `expr` evaluates to a
669-
/// `&SliceInfo` instance used to slice the array.
670-
/// * `expr`: creates an `ArrayView`, where `expr` evaluates to a `&SliceInfo`
671-
/// instance used to slice the array.
668+
/// * `mut` *s-args-or-expr*: creates an `ArrayViewMut` or
669+
/// * *s-args-or-expr*: creates an `ArrayView`
670+
///
671+
/// where *s-args-or-expr* is either (1) arguments enclosed in `[]` to pass to
672+
/// the [`s!`] macro to create a `&SliceInfo` instance or (2) an expression
673+
/// that evaluates to a `&SliceInfo` instance.
672674
///
673675
/// **Note** that this macro always mutably borrows the array even if there are
674676
/// no `mut` patterns. If all you want to do is take read-only slices, you
@@ -700,7 +702,7 @@ pub unsafe fn deref_raw_view_mut_into_view_mut_with_life<'a, A, D: Dimension>(
700702
///
701703
/// # fn main() {
702704
/// let mut arr = Array1::from_iter(0..12);
703-
/// let (a, b, c, d) = multislice!(arr, (s![0..5], mut s![6..;2], s![1..6], mut s![7..;2]));
705+
/// let (a, b, c, d) = multislice!(arr, ([0..5], mut [6..;2], [1..6], mut [7..;2]));
704706
/// assert_eq!(a, array![0, 1, 2, 3, 4]);
705707
/// assert_eq!(b, array![6, 8, 10]);
706708
/// assert_eq!(c, array![1, 2, 3, 4, 5]);
@@ -718,7 +720,7 @@ pub unsafe fn deref_raw_view_mut_into_view_mut_with_life<'a, A, D: Dimension>(
718720
/// # use ndarray::prelude::*;
719721
/// # fn main() {
720722
/// let mut arr = Array1::from_iter(0..12);
721-
/// multislice!(arr, (s![0..5], mut s![1..;2])); // panic!
723+
/// multislice!(arr, ([0..5], mut [1..;2])); // panic!
722724
/// # }
723725
/// ```
724726
///
@@ -730,7 +732,7 @@ pub unsafe fn deref_raw_view_mut_into_view_mut_with_life<'a, A, D: Dimension>(
730732
/// # use ndarray::prelude::*;
731733
/// # fn main() {
732734
/// let mut arr = Array1::from_iter(0..12);
733-
/// multislice!(arr, (mut s![0..5], mut s![1..;2])); // panic!
735+
/// multislice!(arr, (mut [0..5], mut [1..;2])); // panic!
734736
/// # }
735737
/// ```
736738
#[macro_export]
@@ -770,6 +772,108 @@ macro_rules! multislice(
770772
)
771773
}
772774
};
775+
// Parse last slice (mutable), no trailing comma, applying `s![]` macro.
776+
(
777+
@parse $view:expr, $life:expr,
778+
($($sliced:tt)*),
779+
($($mut_info:tt)*),
780+
($($immut_info:tt)*),
781+
(mut [$($info:tt)*])
782+
) => {
783+
// Apply `s![]` macro to info.
784+
$crate::multislice!(
785+
@parse $view, $life,
786+
($($sliced)*),
787+
($($mut_info)*),
788+
($($immut_info)*),
789+
(mut $crate::s![$($info)*],)
790+
)
791+
};
792+
// Parse last slice (read-only), no trailing comma, applying `s![]` macro.
793+
(
794+
@parse $view:expr, $life:expr,
795+
($($sliced:tt)*),
796+
($($mut_info:tt)*),
797+
($($immut_info:tt)*),
798+
([$($info:tt)*])
799+
) => {
800+
// Apply `s![]` macro to info.
801+
$crate::multislice!(
802+
@parse $view, $life,
803+
($($sliced)*),
804+
($($mut_info)*),
805+
($($immut_info)*),
806+
($crate::s![$($info)*],)
807+
)
808+
};
809+
// Parse last slice (mutable), with trailing comma, applying `s![]` macro.
810+
(
811+
@parse $view:expr, $life:expr,
812+
($($sliced:tt)*),
813+
($($mut_info:tt)*),
814+
($($immut_info:tt)*),
815+
(mut [$($info:tt)*],)
816+
) => {
817+
// Apply `s![]` macro to info.
818+
$crate::multislice!(
819+
@parse $view, $life,
820+
($($sliced)*),
821+
($($mut_info)*),
822+
($($immut_info)*),
823+
(mut $crate::s![$($info)*],)
824+
)
825+
};
826+
// Parse last slice (read-only), with trailing comma, applying `s![]` macro.
827+
(
828+
@parse $view:expr, $life:expr,
829+
($($sliced:tt)*),
830+
($($mut_info:tt)*),
831+
($($immut_info:tt)*),
832+
([$($info:tt)*],)
833+
) => {
834+
// Apply `s![]` macro to info.
835+
$crate::multislice!(
836+
@parse $view, $life,
837+
($($sliced)*),
838+
($($mut_info)*),
839+
($($immut_info)*),
840+
($crate::s![$($info)*],)
841+
)
842+
};
843+
// Parse a mutable slice, applying `s![]` macro.
844+
(
845+
@parse $view:expr, $life:expr,
846+
($($sliced:tt)*),
847+
($($mut_info:tt)*),
848+
($($immut_info:tt)*),
849+
(mut [$($info:tt)*], $($t:tt)*)
850+
) => {
851+
// Apply `s![]` macro to info.
852+
$crate::multislice!(
853+
@parse $view, $life,
854+
($($sliced)*),
855+
($($mut_info)*),
856+
($($immut_info)*),
857+
(mut $crate::s![$($info)*], $($t)*)
858+
)
859+
};
860+
// Parse a read-only slice, applying `s![]` macro.
861+
(
862+
@parse $view:expr, $life:expr,
863+
($($sliced:tt)*),
864+
($($mut_info:tt)*),
865+
($($immut_info:tt)*),
866+
([$($info:tt)*], $($t:tt)*)
867+
) => {
868+
// Apply `s![]` macro to info.
869+
$crate::multislice!(
870+
@parse $view, $life,
871+
($($sliced)*),
872+
($($mut_info)*),
873+
($($immut_info)*),
874+
($crate::s![$($info)*], $($t)*)
875+
)
876+
};
773877
// Parse last slice (mutable), no trailing comma.
774878
(
775879
@parse $view:expr, $life:expr,

tests/array.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ fn test_multislice() {
363363
});
364364
let mut arr = Array1::from_iter(0..48).into_shape((8, 6)).unwrap();
365365

366-
assert_eq!((arr.clone().view(),), multislice!(arr, (s![.., ..],)));
366+
assert_eq!((arr.clone().view(),), multislice!(arr, ([.., ..],)));
367367
test_multislice!(&mut arr, s![0, ..], s![1, ..]);
368368
test_multislice!(&mut arr, s![0, ..], s![-1, ..]);
369369
test_multislice!(&mut arr, s![0, ..], s![1.., ..]);
@@ -378,27 +378,27 @@ fn test_multislice() {
378378
fn test_multislice_intersecting() {
379379
assert_panics!({
380380
let mut arr = Array2::<u8>::zeros((8, 6));
381-
multislice!(arr, (mut s![3, ..], s![3, ..]));
381+
multislice!(arr, (mut [3, ..], [3, ..]));
382382
});
383383
assert_panics!({
384384
let mut arr = Array2::<u8>::zeros((8, 6));
385-
multislice!(arr, (mut s![3, ..], s![3.., ..]));
385+
multislice!(arr, (mut [3, ..], [3.., ..]));
386386
});
387387
assert_panics!({
388388
let mut arr = Array2::<u8>::zeros((8, 6));
389-
multislice!(arr, (mut s![3, ..], s![..;3, ..]));
389+
multislice!(arr, (mut [3, ..], [..;3, ..]));
390390
});
391391
assert_panics!({
392392
let mut arr = Array2::<u8>::zeros((8, 6));
393-
multislice!(arr, (mut s![..;6, ..], s![3..;3, ..]));
393+
multislice!(arr, (mut [..;6, ..], [3..;3, ..]));
394394
});
395395
assert_panics!({
396396
let mut arr = Array2::<u8>::zeros((8, 6));
397-
multislice!(arr, (mut s![2, ..], mut s![..-1;-2, ..]));
397+
multislice!(arr, (mut [2, ..], mut [..-1;-2, ..]));
398398
});
399399
{
400400
let mut arr = Array2::<u8>::zeros((8, 6));
401-
multislice!(arr, (s![3, ..], s![-1..;-2, ..]));
401+
multislice!(arr, ([3, ..], [-1..;-2, ..]));
402402
}
403403
}
404404

@@ -411,7 +411,7 @@ fn test_multislice_eval_args_only_once() {
411411
eval_count += 1;
412412
s![1..2].clone()
413413
};
414-
multislice!(arr, (mut &slice(), s![3..4], s![5..6]));
414+
multislice!(arr, (mut &slice(), [3..4], [5..6]));
415415
}
416416
assert_eq!(eval_count, 1);
417417
let mut eval_count = 0;
@@ -420,7 +420,7 @@ fn test_multislice_eval_args_only_once() {
420420
eval_count += 1;
421421
s![1..2].clone()
422422
};
423-
multislice!(arr, (s![3..4], mut &slice(), s![5..6]));
423+
multislice!(arr, ([3..4], mut &slice(), [5..6]));
424424
}
425425
assert_eq!(eval_count, 1);
426426
let mut eval_count = 0;
@@ -429,7 +429,7 @@ fn test_multislice_eval_args_only_once() {
429429
eval_count += 1;
430430
s![1..2].clone()
431431
};
432-
multislice!(arr, (s![3..4], s![5..6], mut &slice()));
432+
multislice!(arr, ([3..4], [5..6], mut &slice()));
433433
}
434434
assert_eq!(eval_count, 1);
435435
let mut eval_count = 0;
@@ -438,7 +438,7 @@ fn test_multislice_eval_args_only_once() {
438438
eval_count += 1;
439439
s![1..2].clone()
440440
};
441-
multislice!(arr, (&slice(), mut s![3..4], s![5..6]));
441+
multislice!(arr, (&slice(), mut [3..4], [5..6]));
442442
}
443443
assert_eq!(eval_count, 1);
444444
let mut eval_count = 0;
@@ -447,7 +447,7 @@ fn test_multislice_eval_args_only_once() {
447447
eval_count += 1;
448448
s![1..2].clone()
449449
};
450-
multislice!(arr, (mut s![3..4], &slice(), s![5..6]));
450+
multislice!(arr, (mut [3..4], &slice(), [5..6]));
451451
}
452452
assert_eq!(eval_count, 1);
453453
let mut eval_count = 0;
@@ -456,7 +456,7 @@ fn test_multislice_eval_args_only_once() {
456456
eval_count += 1;
457457
s![1..2].clone()
458458
};
459-
multislice!(arr, (mut s![3..4], s![5..6], &slice()));
459+
multislice!(arr, (mut [3..4], [5..6], &slice()));
460460
}
461461
assert_eq!(eval_count, 1);
462462
}

0 commit comments

Comments
 (0)