Skip to content

Commit 1444fcf

Browse files
committed
nonzero baby steps
1 parent 483200b commit 1444fcf

File tree

4 files changed

+24
-52
lines changed

4 files changed

+24
-52
lines changed

src/dimension/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,7 @@ fn to_abs_slice(axis_len: usize, slice: Slice) -> (usize, usize, isize) {
360360
end,
361361
axis_len,
362362
);
363-
ndassert!(step != 0, "Slice stride must not be zero");
364-
(start, end, step)
363+
(start, end, step.get())
365364
}
366365

367366
/// Modify dimension, stride and return data pointer offset

src/impl_methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ where
413413
.enumerate()
414414
.for_each(|(axis, &slice_or_index)| match slice_or_index {
415415
SliceOrIndex::Slice { start, end, step } => {
416-
self.slice_axis_inplace(Axis(axis), Slice { start, end, step })
416+
self.slice_axis_inplace(Axis(axis), Slice::new(start, end, step))
417417
}
418418
SliceOrIndex::Index(index) => {
419419
let i_usize = abs_index(self.len_of(Axis(axis)), index);

src/slice.rs

+21-48
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::error::{ErrorKind, ShapeError};
99
use crate::{ArrayView, ArrayViewMut, Dimension, RawArrayViewMut};
1010
use std::fmt;
1111
use std::marker::PhantomData;
12+
use std::num::NonZeroIsize;
1213
use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
1314

1415
/// A slice (range with step size).
@@ -35,7 +36,7 @@ use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, Rang
3536
pub struct Slice {
3637
pub start: isize,
3738
pub end: Option<isize>,
38-
pub step: isize,
39+
pub step: NonZeroIsize,
3940
}
4041

4142
impl Slice {
@@ -47,25 +48,17 @@ impl Slice {
4748
/// `step` must be nonzero.
4849
/// (This method checks with a debug assertion that `step` is not zero.)
4950
pub fn new(start: isize, end: Option<isize>, step: isize) -> Slice {
50-
debug_assert_ne!(step, 0, "Slice::new: step must be nonzero");
51-
Slice { start, end, step }
52-
}
53-
54-
/// Create a new `Slice` with the given step size (multiplied with the
55-
/// previous step size).
56-
///
57-
/// `step` must be nonzero.
58-
/// (This method checks with a debug assertion that `step` is not zero.)
59-
#[inline]
60-
pub fn step_by(self, step: isize) -> Self {
61-
debug_assert_ne!(step, 0, "Slice::step_by: step must be nonzero");
6251
Slice {
63-
step: self.step * step,
64-
..self
52+
start,
53+
end,
54+
step: NonZeroIsize::new(step).expect("Slice::new: step must be nonzero"),
6555
}
6656
}
6757
}
6858

59+
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
60+
struct Index(isize);
61+
6962
/// A slice (range with step) or an index.
7063
///
7164
/// See also the [`s![]`](macro.s!.html) macro for a convenient way to create a
@@ -130,7 +123,6 @@ impl SliceOrIndex {
130123
/// (This method checks with a debug assertion that `step` is not zero.)
131124
#[inline]
132125
pub fn step_by(self, step: isize) -> Self {
133-
debug_assert_ne!(step, 0, "SliceOrIndex::step_by: step must be nonzero");
134126
match self {
135127
SliceOrIndex::Slice {
136128
start,
@@ -172,57 +164,42 @@ macro_rules! impl_slice_variant_from_range {
172164
impl From<Range<$index>> for $self {
173165
#[inline]
174166
fn from(r: Range<$index>) -> $self {
175-
$constructor {
176-
start: r.start as isize,
177-
end: Some(r.end as isize),
178-
step: 1,
179-
}
167+
Slice::new(r.start as isize, Some(r.end as isize), 1).into()
180168
}
181169
}
182170

183171
impl From<RangeInclusive<$index>> for $self {
184172
#[inline]
185173
fn from(r: RangeInclusive<$index>) -> $self {
186174
let end = *r.end() as isize;
187-
$constructor {
188-
start: *r.start() as isize,
189-
end: if end == -1 { None } else { Some(end + 1) },
190-
step: 1,
191-
}
175+
Slice::new(
176+
*r.start() as isize,
177+
if end == -1 { None } else { Some(end + 1) },
178+
1,
179+
)
180+
.into()
192181
}
193182
}
194183

195184
impl From<RangeFrom<$index>> for $self {
196185
#[inline]
197186
fn from(r: RangeFrom<$index>) -> $self {
198-
$constructor {
199-
start: r.start as isize,
200-
end: None,
201-
step: 1,
202-
}
187+
Slice::new(r.start as isize, None, 1).into()
203188
}
204189
}
205190

206191
impl From<RangeTo<$index>> for $self {
207192
#[inline]
208193
fn from(r: RangeTo<$index>) -> $self {
209-
$constructor {
210-
start: 0,
211-
end: Some(r.end as isize),
212-
step: 1,
213-
}
194+
Slice::new(0, Some(r.end as isize), 1).into()
214195
}
215196
}
216197

217198
impl From<RangeToInclusive<$index>> for $self {
218199
#[inline]
219200
fn from(r: RangeToInclusive<$index>) -> $self {
220201
let end = r.end as isize;
221-
$constructor {
222-
start: 0,
223-
end: if end == -1 { None } else { Some(end + 1) },
224-
step: 1,
225-
}
202+
Slice::new(0, if end == -1 { None } else { Some(end + 1) }, 1).into()
226203
}
227204
}
228205
};
@@ -237,11 +214,7 @@ impl_slice_variant_from_range!(SliceOrIndex, SliceOrIndex::Slice, i32);
237214
impl From<RangeFull> for Slice {
238215
#[inline]
239216
fn from(_: RangeFull) -> Slice {
240-
Slice {
241-
start: 0,
242-
end: None,
243-
step: 1,
244-
}
217+
Slice::new(0, None, 1)
245218
}
246219
}
247220

@@ -262,7 +235,7 @@ impl From<Slice> for SliceOrIndex {
262235
SliceOrIndex::Slice {
263236
start: s.start,
264237
end: s.end,
265-
step: s.step,
238+
step: s.step.get(),
266239
}
267240
}
268241
}
@@ -610,7 +583,7 @@ macro_rules! s(
610583
};
611584
// convert range/index and step into SliceOrIndex
612585
(@convert $r:expr, $s:expr) => {
613-
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s as isize)
586+
<$crate::SliceOrIndex as ::std::convert::From<_>>::from($r).step_by($s)
614587
};
615588
($($t:tt)*) => {
616589
// The extra `*&` is a workaround for this compiler bug:

tests/array.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ fn test_slice_dyninput_vec_dyn() {
257257
let info = &SliceInfo::<_, IxDyn>::new(vec![
258258
SliceOrIndex::from(1..),
259259
SliceOrIndex::from(1),
260-
SliceOrIndex::from(..).step_by(2),
260+
SliceOrIndex::from(..).step_by(2isize),
261261
])
262262
.unwrap();
263263
arr.slice(info.as_ref());

0 commit comments

Comments
 (0)