6
6
// option. This file may not be copied, modified, or distributed
7
7
// except according to those terms.
8
8
9
- use { Ix , Ixs } ;
9
+ use { Ix , Ixs , Slice } ;
10
10
use error:: { from_kind, ErrorKind , ShapeError } ;
11
11
12
12
pub use self :: dim:: * ;
@@ -222,25 +222,18 @@ pub fn abs_index(len: Ix, index: Ixs) -> Ix {
222
222
}
223
223
}
224
224
225
- /// Modify dimension, stride and return data pointer offset
225
+ /// Determines nonnegative start and end indices, and performs sanity checks.
226
+ ///
227
+ /// The return value is (start, end, step).
226
228
///
227
229
/// **Panics** if stride is 0 or if any index is out of bounds.
228
- pub fn do_slice (
229
- dim : & mut Ix ,
230
- stride : & mut Ix ,
231
- start : Ixs ,
232
- end : Option < Ixs > ,
233
- step : Ixs ,
234
- ) -> isize {
235
- let mut offset = 0 ;
236
-
237
- let axis_len = * dim;
230
+ fn to_abs_slice ( axis_len : usize , slice : Slice ) -> ( usize , usize , isize ) {
231
+ let Slice { start, end, step } = slice;
238
232
let start = abs_index ( axis_len, start) ;
239
- let mut end = abs_index ( axis_len, end. unwrap_or ( axis_len as Ixs ) ) ;
233
+ let mut end = abs_index ( axis_len, end. unwrap_or ( axis_len as isize ) ) ;
240
234
if end < start {
241
235
end = start;
242
236
}
243
-
244
237
ndassert ! (
245
238
start <= axis_len,
246
239
"Slice begin {} is past end of axis of length {}" ,
@@ -253,15 +246,23 @@ pub fn do_slice(
253
246
end,
254
247
axis_len,
255
248
) ;
249
+ ndassert ! ( step != 0 , "Slice stride must not be zero" ) ;
250
+ ( start, end, step)
251
+ }
252
+
253
+ /// Modify dimension, stride and return data pointer offset
254
+ ///
255
+ /// **Panics** if stride is 0 or if any index is out of bounds.
256
+ pub fn do_slice ( dim : & mut usize , stride : & mut usize , slice : Slice ) -> isize {
257
+ let ( start, end, step) = to_abs_slice ( * dim, slice) ;
256
258
257
259
let m = end - start;
258
- // stride
259
- let s = ( * stride) as Ixs ;
260
+ let s = ( * stride) as isize ;
260
261
261
262
// Data pointer offset
262
- offset + = stride_offset ( start, * stride) ;
263
+ let mut offset = stride_offset ( start, * stride) ;
263
264
// Adjust for strides
264
- ndassert ! ( step != 0 , "Slice stride must not be zero" ) ;
265
+ //
265
266
// How to implement negative strides:
266
267
//
267
268
// Increase start pointer by
@@ -273,13 +274,13 @@ pub fn do_slice(
273
274
274
275
let s_prim = s * step;
275
276
276
- let d = m / step. abs ( ) as Ix ;
277
- let r = m % step. abs ( ) as Ix ;
277
+ let d = m / step. abs ( ) as usize ;
278
+ let r = m % step. abs ( ) as usize ;
278
279
let m_prim = d + if r > 0 { 1 } else { 0 } ;
279
280
280
281
// Update dimension and stride coordinate
281
282
* dim = m_prim;
282
- * stride = s_prim as Ix ;
283
+ * stride = s_prim as usize ;
283
284
284
285
offset
285
286
}
0 commit comments