@@ -9,6 +9,7 @@ use crate::error::{ErrorKind, ShapeError};
9
9
use crate :: { ArrayView , ArrayViewMut , Dimension , RawArrayViewMut } ;
10
10
use std:: fmt;
11
11
use std:: marker:: PhantomData ;
12
+ use std:: num:: NonZeroIsize ;
12
13
use std:: ops:: { Deref , Range , RangeFrom , RangeFull , RangeInclusive , RangeTo , RangeToInclusive } ;
13
14
14
15
/// A slice (range with step size).
@@ -35,7 +36,7 @@ use std::ops::{Deref, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, Rang
35
36
pub struct Slice {
36
37
pub start : isize ,
37
38
pub end : Option < isize > ,
38
- pub step : isize ,
39
+ pub step : NonZeroIsize ,
39
40
}
40
41
41
42
impl Slice {
@@ -47,25 +48,17 @@ impl Slice {
47
48
/// `step` must be nonzero.
48
49
/// (This method checks with a debug assertion that `step` is not zero.)
49
50
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" ) ;
62
51
Slice {
63
- step : self . step * step,
64
- ..self
52
+ start,
53
+ end,
54
+ step : NonZeroIsize :: new ( step) . expect ( "Slice::new: step must be nonzero" ) ,
65
55
}
66
56
}
67
57
}
68
58
59
+ #[ derive( Debug , PartialEq , Eq , Hash , Copy , Clone ) ]
60
+ struct Index ( isize ) ;
61
+
69
62
/// A slice (range with step) or an index.
70
63
///
71
64
/// See also the [`s![]`](macro.s!.html) macro for a convenient way to create a
@@ -130,7 +123,6 @@ impl SliceOrIndex {
130
123
/// (This method checks with a debug assertion that `step` is not zero.)
131
124
#[ inline]
132
125
pub fn step_by ( self , step : isize ) -> Self {
133
- debug_assert_ne ! ( step, 0 , "SliceOrIndex::step_by: step must be nonzero" ) ;
134
126
match self {
135
127
SliceOrIndex :: Slice {
136
128
start,
@@ -172,57 +164,42 @@ macro_rules! impl_slice_variant_from_range {
172
164
impl From <Range <$index>> for $self {
173
165
#[ inline]
174
166
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( )
180
168
}
181
169
}
182
170
183
171
impl From <RangeInclusive <$index>> for $self {
184
172
#[ inline]
185
173
fn from( r: RangeInclusive <$index>) -> $self {
186
174
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( )
192
181
}
193
182
}
194
183
195
184
impl From <RangeFrom <$index>> for $self {
196
185
#[ inline]
197
186
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( )
203
188
}
204
189
}
205
190
206
191
impl From <RangeTo <$index>> for $self {
207
192
#[ inline]
208
193
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( )
214
195
}
215
196
}
216
197
217
198
impl From <RangeToInclusive <$index>> for $self {
218
199
#[ inline]
219
200
fn from( r: RangeToInclusive <$index>) -> $self {
220
201
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( )
226
203
}
227
204
}
228
205
} ;
@@ -237,11 +214,7 @@ impl_slice_variant_from_range!(SliceOrIndex, SliceOrIndex::Slice, i32);
237
214
impl From < RangeFull > for Slice {
238
215
#[ inline]
239
216
fn from ( _: RangeFull ) -> Slice {
240
- Slice {
241
- start : 0 ,
242
- end : None ,
243
- step : 1 ,
244
- }
217
+ Slice :: new ( 0 , None , 1 )
245
218
}
246
219
}
247
220
@@ -262,7 +235,7 @@ impl From<Slice> for SliceOrIndex {
262
235
SliceOrIndex :: Slice {
263
236
start : s. start ,
264
237
end : s. end ,
265
- step : s. step ,
238
+ step : s. step . get ( ) ,
266
239
}
267
240
}
268
241
}
@@ -610,7 +583,7 @@ macro_rules! s(
610
583
} ;
611
584
// convert range/index and step into SliceOrIndex
612
585
( @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)
614
587
} ;
615
588
( $( $t: tt) * ) => {
616
589
// The extra `*&` is a workaround for this compiler bug:
0 commit comments