Skip to content

Commit 2bcbb2a

Browse files
authored
Merge pull request #940 from jturner314/make-sliceinfo-sized
Simplifications for slicing-related types
2 parents d399751 + fb7e94d commit 2bcbb2a

File tree

6 files changed

+60
-69
lines changed

6 files changed

+60
-69
lines changed

src/dimension/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,8 @@ fn slice_min_max(axis_len: usize, slice: Slice) -> Option<(usize, usize)> {
599599
/// Returns `true` iff the slices intersect.
600600
pub fn slices_intersect<D: Dimension>(
601601
dim: &D,
602-
indices1: &impl SliceArg<D>,
603-
indices2: &impl SliceArg<D>,
602+
indices1: impl SliceArg<D>,
603+
indices2: impl SliceArg<D>,
604604
) -> bool {
605605
debug_assert_eq!(indices1.in_ndim(), indices2.in_ndim());
606606
for (&axis_len, &si1, &si2) in izip!(

src/impl_methods.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,9 @@ where
338338
///
339339
/// **Panics** if an index is out of bounds or step size is zero.<br>
340340
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
341-
pub fn slice<I>(&self, info: &I) -> ArrayView<'_, A, I::OutDim>
341+
pub fn slice<I>(&self, info: I) -> ArrayView<'_, A, I::OutDim>
342342
where
343-
I: SliceArg<D> + ?Sized,
343+
I: SliceArg<D>,
344344
S: Data,
345345
{
346346
self.view().slice_move(info)
@@ -353,9 +353,9 @@ where
353353
///
354354
/// **Panics** if an index is out of bounds or step size is zero.<br>
355355
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
356-
pub fn slice_mut<I>(&mut self, info: &I) -> ArrayViewMut<'_, A, I::OutDim>
356+
pub fn slice_mut<I>(&mut self, info: I) -> ArrayViewMut<'_, A, I::OutDim>
357357
where
358-
I: SliceArg<D> + ?Sized,
358+
I: SliceArg<D>,
359359
S: DataMut,
360360
{
361361
self.view_mut().slice_move(info)
@@ -399,9 +399,9 @@ where
399399
///
400400
/// **Panics** if an index is out of bounds or step size is zero.<br>
401401
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
402-
pub fn slice_move<I>(mut self, info: &I) -> ArrayBase<S, I::OutDim>
402+
pub fn slice_move<I>(mut self, info: I) -> ArrayBase<S, I::OutDim>
403403
where
404-
I: SliceArg<D> + ?Sized,
404+
I: SliceArg<D>,
405405
{
406406
assert_eq!(
407407
info.in_ndim(),
@@ -468,9 +468,9 @@ where
468468
/// - if [`AxisSliceInfo::NewAxis`] is in `info`, e.g. if [`NewAxis`] was
469469
/// used in the [`s!`] macro
470470
/// - if `D` is `IxDyn` and `info` does not match the number of array axes
471-
pub fn slice_collapse<I>(&mut self, info: &I)
471+
pub fn slice_collapse<I>(&mut self, info: I)
472472
where
473-
I: SliceArg<D> + ?Sized,
473+
I: SliceArg<D>,
474474
{
475475
assert_eq!(
476476
info.in_ndim(),

src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,8 @@ pub type Ixs = isize;
494494
///
495495
/// The slicing argument can be passed using the macro [`s![]`](macro.s!.html),
496496
/// which will be used in all examples. (The explicit form is an instance of
497-
/// [`&SliceInfo`]; see its docs for more information.)
498-
///
499-
/// [`&SliceInfo`]: struct.SliceInfo.html
497+
/// [`SliceInfo`] or another type which implements [`SliceArg`]; see their docs
498+
/// for more information.)
500499
///
501500
/// If a range is used, the axis is preserved. If an index is used, that index
502501
/// is selected and the axis is removed; this selects a subview. See
@@ -512,7 +511,7 @@ pub type Ixs = isize;
512511
/// [`NewAxis`]: struct.NewAxis.html
513512
///
514513
/// When slicing arrays with generic dimensionality, creating an instance of
515-
/// [`&SliceInfo`] to pass to the multi-axis slicing methods like [`.slice()`]
514+
/// [`SliceInfo`] to pass to the multi-axis slicing methods like [`.slice()`]
516515
/// is awkward. In these cases, it's usually more convenient to use
517516
/// [`.slice_each_axis()`]/[`.slice_each_axis_mut()`]/[`.slice_each_axis_inplace()`]
518517
/// or to create a view and then slice individual axes of the view using

src/slice.rs

Lines changed: 40 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub struct NewAxis;
7878
/// A slice (range with step), an index, or a new axis token.
7979
///
8080
/// See also the [`s![]`](macro.s!.html) macro for a convenient way to create a
81-
/// `&SliceInfo<[AxisSliceInfo; n], Din, Dout>`.
81+
/// `SliceInfo<[AxisSliceInfo; n], Din, Dout>`.
8282
///
8383
/// ## Examples
8484
///
@@ -324,6 +324,24 @@ pub unsafe trait SliceArg<D: Dimension>: AsRef<[AxisSliceInfo]> {
324324
private_decl! {}
325325
}
326326

327+
unsafe impl<T, D> SliceArg<D> for &T
328+
where
329+
T: SliceArg<D> + ?Sized,
330+
D: Dimension,
331+
{
332+
type OutDim = T::OutDim;
333+
334+
fn in_ndim(&self) -> usize {
335+
T::in_ndim(self)
336+
}
337+
338+
fn out_ndim(&self) -> usize {
339+
T::out_ndim(self)
340+
}
341+
342+
private_impl! {}
343+
}
344+
327345
macro_rules! impl_slicearg_samedim {
328346
($in_dim:ty) => {
329347
unsafe impl<T, Dout> SliceArg<$in_dim> for SliceInfo<T, $in_dim, Dout>
@@ -388,7 +406,7 @@ unsafe impl SliceArg<IxDyn> for [AxisSliceInfo] {
388406

389407
/// Represents all of the necessary information to perform a slice.
390408
///
391-
/// The type `T` is typically `[AxisSliceInfo; n]`, `[AxisSliceInfo]`, or
409+
/// The type `T` is typically `[AxisSliceInfo; n]`, `&[AxisSliceInfo]`, or
392410
/// `Vec<AxisSliceInfo>`. The type `Din` is the dimension of the array to be
393411
/// sliced, and `Dout` is the output dimension after calling [`.slice()`]. Note
394412
/// that if `Din` is a fixed dimension type (`Ix0`, `Ix1`, `Ix2`, etc.), the
@@ -397,14 +415,13 @@ unsafe impl SliceArg<IxDyn> for [AxisSliceInfo] {
397415
///
398416
/// [`.slice()`]: struct.ArrayBase.html#method.slice
399417
#[derive(Debug)]
400-
#[repr(transparent)]
401-
pub struct SliceInfo<T: ?Sized, Din: Dimension, Dout: Dimension> {
418+
pub struct SliceInfo<T, Din: Dimension, Dout: Dimension> {
402419
in_dim: PhantomData<Din>,
403420
out_dim: PhantomData<Dout>,
404421
indices: T,
405422
}
406423

407-
impl<T: ?Sized, Din, Dout> Deref for SliceInfo<T, Din, Dout>
424+
impl<T, Din, Dout> Deref for SliceInfo<T, Din, Dout>
408425
where
409426
Din: Dimension,
410427
Dout: Dimension,
@@ -464,14 +481,7 @@ where
464481
indices,
465482
}
466483
}
467-
}
468484

469-
impl<T, Din, Dout> SliceInfo<T, Din, Dout>
470-
where
471-
T: AsRef<[AxisSliceInfo]>,
472-
Din: Dimension,
473-
Dout: Dimension,
474-
{
475485
/// Returns a new `SliceInfo` instance.
476486
///
477487
/// Errors if `Din` or `Dout` is not consistent with `indices`.
@@ -490,14 +500,7 @@ where
490500
indices,
491501
})
492502
}
493-
}
494503

495-
impl<T: ?Sized, Din, Dout> SliceInfo<T, Din, Dout>
496-
where
497-
T: AsRef<[AxisSliceInfo]>,
498-
Din: Dimension,
499-
Dout: Dimension,
500-
{
501504
/// Returns the number of dimensions of the input array for
502505
/// [`.slice()`](struct.ArrayBase.html#method.slice).
503506
///
@@ -528,7 +531,7 @@ where
528531
}
529532
}
530533

531-
impl<'a, Din, Dout> TryFrom<&'a [AxisSliceInfo]> for &'a SliceInfo<[AxisSliceInfo], Din, Dout>
534+
impl<'a, Din, Dout> TryFrom<&'a [AxisSliceInfo]> for SliceInfo<&'a [AxisSliceInfo], Din, Dout>
532535
where
533536
Din: Dimension,
534537
Dout: Dimension,
@@ -537,16 +540,11 @@ where
537540

538541
fn try_from(
539542
indices: &'a [AxisSliceInfo],
540-
) -> Result<&'a SliceInfo<[AxisSliceInfo], Din, Dout>, ShapeError> {
541-
check_dims_for_sliceinfo::<Din, Dout>(indices)?;
543+
) -> Result<SliceInfo<&'a [AxisSliceInfo], Din, Dout>, ShapeError> {
542544
unsafe {
543-
// This is okay because we've already checked the correctness of
544-
// `Din` and `Dout`, and the only non-zero-sized member of
545-
// `SliceInfo` is `indices`, so `&SliceInfo<[AxisSliceInfo], Din,
546-
// Dout>` should have the same bitwise representation as
547-
// `&[AxisSliceInfo]`.
548-
Ok(&*(indices as *const [AxisSliceInfo]
549-
as *const SliceInfo<[AxisSliceInfo], Din, Dout>))
545+
// This is okay because `&[AxisSliceInfo]` always returns the same
546+
// value for `.as_ref()`.
547+
Self::new(indices)
550548
}
551549
}
552550
}
@@ -612,20 +610,18 @@ where
612610
}
613611
}
614612

615-
impl<T, Din, Dout> AsRef<SliceInfo<[AxisSliceInfo], Din, Dout>> for SliceInfo<T, Din, Dout>
613+
impl<'a, T, Din, Dout> From<&'a SliceInfo<T, Din, Dout>>
614+
for SliceInfo<&'a [AxisSliceInfo], Din, Dout>
616615
where
617616
T: AsRef<[AxisSliceInfo]>,
618617
Din: Dimension,
619618
Dout: Dimension,
620619
{
621-
fn as_ref(&self) -> &SliceInfo<[AxisSliceInfo], Din, Dout> {
622-
unsafe {
623-
// This is okay because the only non-zero-sized member of
624-
// `SliceInfo` is `indices`, so `&SliceInfo<[AxisSliceInfo], Din, Dout>`
625-
// should have the same bitwise representation as
626-
// `&[AxisSliceInfo]`.
627-
&*(self.indices.as_ref() as *const [AxisSliceInfo]
628-
as *const SliceInfo<[AxisSliceInfo], Din, Dout>)
620+
fn from(info: &'a SliceInfo<T, Din, Dout>) -> SliceInfo<&'a [AxisSliceInfo], Din, Dout> {
621+
SliceInfo {
622+
in_dim: info.in_dim,
623+
out_dim: info.out_dim,
624+
indices: info.indices.as_ref(),
629625
}
630626
}
631627
}
@@ -703,9 +699,7 @@ impl_slicenextdim!((), NewAxis, Ix0, Ix1);
703699
///
704700
/// `s![]` takes a list of ranges/slices/indices/new-axes, separated by comma,
705701
/// with optional step sizes that are separated from the range by a semicolon.
706-
/// It is converted into a [`&SliceInfo`] instance.
707-
///
708-
/// [`&SliceInfo`]: struct.SliceInfo.html
702+
/// It is converted into a [`SliceInfo`] instance.
709703
///
710704
/// Each range/slice/index uses signed indices, where a negative value is
711705
/// counted from the end of the axis. Step sizes are also signed and may be
@@ -889,9 +883,7 @@ macro_rules! s(
889883
<$crate::AxisSliceInfo as ::std::convert::From<_>>::from($r).step_by($s as isize)
890884
};
891885
($($t:tt)*) => {
892-
// The extra `*&` is a workaround for this compiler bug:
893-
// https://github.com/rust-lang/rust/issues/23014
894-
&*&$crate::s![@parse
886+
$crate::s![@parse
895887
::std::marker::PhantomData::<$crate::Ix0>,
896888
::std::marker::PhantomData::<$crate::Ix0>,
897889
[]
@@ -933,7 +925,7 @@ where
933925
private_impl! {}
934926
}
935927

936-
impl<'a, A, D, I0> MultiSliceArg<'a, A, D> for (&I0,)
928+
impl<'a, A, D, I0> MultiSliceArg<'a, A, D> for (I0,)
937929
where
938930
A: 'a,
939931
D: Dimension,
@@ -942,7 +934,7 @@ where
942934
type Output = (ArrayViewMut<'a, A, I0::OutDim>,);
943935

944936
fn multi_slice_move(&self, view: ArrayViewMut<'a, A, D>) -> Self::Output {
945-
(view.slice_move(self.0),)
937+
(view.slice_move(&self.0),)
946938
}
947939

948940
private_impl! {}
@@ -953,7 +945,7 @@ macro_rules! impl_multislice_tuple {
953945
impl_multislice_tuple!(@def_impl ($($but_last,)* $last,), [$($but_last)*] $last);
954946
};
955947
(@def_impl ($($all:ident,)*), [$($but_last:ident)*] $last:ident) => {
956-
impl<'a, A, D, $($all,)*> MultiSliceArg<'a, A, D> for ($(&$all,)*)
948+
impl<'a, A, D, $($all,)*> MultiSliceArg<'a, A, D> for ($($all,)*)
957949
where
958950
A: 'a,
959951
D: Dimension,
@@ -963,7 +955,7 @@ macro_rules! impl_multislice_tuple {
963955

964956
fn multi_slice_move(&self, view: ArrayViewMut<'a, A, D>) -> Self::Output {
965957
#[allow(non_snake_case)]
966-
let &($($all,)*) = self;
958+
let ($($all,)*) = self;
967959

968960
let shape = view.raw_dim();
969961
assert!(!impl_multislice_tuple!(@intersects_self &shape, ($($all,)*)));

tests/array.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ fn test_slice_dyninput_array_fixed() {
219219
#[test]
220220
fn test_slice_array_dyn() {
221221
let mut arr = Array3::<f64>::zeros((5, 2, 5));
222-
let info = &SliceInfo::<_, Ix3, IxDyn>::try_from([
222+
let info = SliceInfo::<_, Ix3, IxDyn>::try_from([
223223
AxisSliceInfo::from(1..),
224224
AxisSliceInfo::from(1),
225225
AxisSliceInfo::from(NewAxis),
@@ -229,7 +229,7 @@ fn test_slice_array_dyn() {
229229
arr.slice(info);
230230
arr.slice_mut(info);
231231
arr.view().slice_move(info);
232-
let info2 = &SliceInfo::<_, Ix3, IxDyn>::try_from([
232+
let info2 = SliceInfo::<_, Ix3, IxDyn>::try_from([
233233
AxisSliceInfo::from(1..),
234234
AxisSliceInfo::from(1),
235235
AxisSliceInfo::from(..).step_by(2),
@@ -241,7 +241,7 @@ fn test_slice_array_dyn() {
241241
#[test]
242242
fn test_slice_dyninput_array_dyn() {
243243
let mut arr = Array3::<f64>::zeros((5, 2, 5)).into_dyn();
244-
let info = &SliceInfo::<_, Ix3, IxDyn>::try_from([
244+
let info = SliceInfo::<_, Ix3, IxDyn>::try_from([
245245
AxisSliceInfo::from(1..),
246246
AxisSliceInfo::from(1),
247247
AxisSliceInfo::from(NewAxis),
@@ -251,7 +251,7 @@ fn test_slice_dyninput_array_dyn() {
251251
arr.slice(info);
252252
arr.slice_mut(info);
253253
arr.view().slice_move(info);
254-
let info2 = &SliceInfo::<_, Ix3, IxDyn>::try_from([
254+
let info2 = SliceInfo::<_, Ix3, IxDyn>::try_from([
255255
AxisSliceInfo::from(1..),
256256
AxisSliceInfo::from(1),
257257
AxisSliceInfo::from(..).step_by(2),
@@ -273,7 +273,7 @@ fn test_slice_dyninput_vec_fixed() {
273273
arr.slice(info);
274274
arr.slice_mut(info);
275275
arr.view().slice_move(info);
276-
let info2 = &SliceInfo::<_, Ix3, Ix2>::try_from(vec![
276+
let info2 = SliceInfo::<_, Ix3, Ix2>::try_from(vec![
277277
AxisSliceInfo::from(1..),
278278
AxisSliceInfo::from(1),
279279
AxisSliceInfo::from(..).step_by(2),
@@ -295,7 +295,7 @@ fn test_slice_dyninput_vec_dyn() {
295295
arr.slice(info);
296296
arr.slice_mut(info);
297297
arr.view().slice_move(info);
298-
let info2 = &SliceInfo::<_, Ix3, IxDyn>::try_from(vec![
298+
let info2 = SliceInfo::<_, Ix3, IxDyn>::try_from(vec![
299299
AxisSliceInfo::from(1..),
300300
AxisSliceInfo::from(1),
301301
AxisSliceInfo::from(..).step_by(2),

tests/oper.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ fn scaled_add_3() {
596596

597597
{
598598
let mut av = a.slice_mut(s![..;s1, ..;s2]);
599-
let c = c.slice(&SliceInfo::<_, IxDyn, IxDyn>::try_from(cslice).unwrap());
599+
let c = c.slice(SliceInfo::<_, IxDyn, IxDyn>::try_from(cslice).unwrap());
600600

601601
let mut answerv = answer.slice_mut(s![..;s1, ..;s2]);
602602
answerv += &(beta * &c);

0 commit comments

Comments
 (0)