@@ -9,7 +9,7 @@ use crate::common::{
9
9
rc:: PyRc ,
10
10
} ;
11
11
use crate :: function:: { FuncArgs , OptionalArg } ;
12
- use crate :: sliceable:: { convert_slice, saturate_range , wrap_index, SequenceIndex } ;
12
+ use crate :: sliceable:: { convert_slice, wrap_index, SequenceIndex } ;
13
13
use crate :: slots:: { AsBuffer , Comparable , Hashable , PyComparisonOp , SlotConstructor } ;
14
14
use crate :: stdlib:: pystruct:: _struct:: FormatSpec ;
15
15
use crate :: utils:: Either ;
@@ -19,8 +19,7 @@ use crate::{
19
19
} ;
20
20
use crossbeam_utils:: atomic:: AtomicCell ;
21
21
use itertools:: Itertools ;
22
- use num_bigint:: BigInt ;
23
- use num_traits:: { One , Signed , ToPrimitive , Zero } ;
22
+ use num_traits:: ToPrimitive ;
24
23
use std:: fmt:: Debug ;
25
24
use std:: ops:: Deref ;
26
25
@@ -255,25 +254,20 @@ impl PyMemoryView {
255
254
256
255
fn getitem_by_slice ( zelf : PyRef < Self > , slice : PySliceRef , vm : & VirtualMachine ) -> PyResult {
257
256
// slicing a memoryview return a new memoryview
258
- let start = slice. start_index ( vm) ?;
259
- let stop = slice. stop_index ( vm) ?;
260
- let step = slice. step_index ( vm) ?. unwrap_or_else ( BigInt :: one) ;
261
- if step. is_zero ( ) {
262
- return Err ( vm. new_value_error ( "slice step cannot be zero" . to_owned ( ) ) ) ;
263
- }
264
- let newstep: BigInt = step. clone ( ) * zelf. step ;
265
257
let len = zelf. buffer . options . len ;
258
+ let ( range, step, is_negative_step) = convert_slice ( & slice, len, vm) ?;
259
+ let abs_step = step. unwrap ( ) ;
260
+ let step = if is_negative_step {
261
+ -( abs_step as isize )
262
+ } else {
263
+ abs_step as isize
264
+ } ;
265
+ let newstep = step * zelf. step ;
266
266
let itemsize = zelf. buffer . options . itemsize ;
267
267
268
268
let format_spec = zelf. format_spec . clone ( ) ;
269
269
270
- if newstep == BigInt :: one ( ) {
271
- let range = saturate_range ( & start, & stop, len) ;
272
- let range = if range. end < range. start {
273
- range. start ..range. start
274
- } else {
275
- range
276
- } ;
270
+ if newstep == 1 {
277
271
let newlen = range. end - range. start ;
278
272
let start = zelf. start + range. start * itemsize;
279
273
let stop = zelf. start + range. end * itemsize;
@@ -294,35 +288,7 @@ impl PyMemoryView {
294
288
. into_object ( vm) ) ;
295
289
}
296
290
297
- let ( start, stop) = if step. is_negative ( ) {
298
- (
299
- stop. map ( |x| {
300
- if x == -BigInt :: one ( ) {
301
- len + BigInt :: one ( )
302
- } else {
303
- x + 1
304
- }
305
- } ) ,
306
- start. map ( |x| {
307
- if x == -BigInt :: one ( ) {
308
- BigInt :: from ( len)
309
- } else {
310
- x + 1
311
- }
312
- } ) ,
313
- )
314
- } else {
315
- ( start, stop)
316
- } ;
317
-
318
- let range = saturate_range ( & start, & stop, len) ;
319
- let newlen = if range. end > range. start {
320
- // overflow is not possible as dividing a positive integer
321
- ( ( range. end - range. start - 1 ) / step. abs ( ) )
322
- . to_usize ( )
323
- . unwrap ( )
324
- + 1
325
- } else {
291
+ if range. start >= range. end {
326
292
return Ok ( PyMemoryView {
327
293
buffer : zelf. buffer . clone_with_options ( BufferOptions {
328
294
len : 0 ,
@@ -340,6 +306,12 @@ impl PyMemoryView {
340
306
. into_object ( vm) ) ;
341
307
} ;
342
308
309
+ // overflow is not possible as dividing a positive integer
310
+ let newlen = ( ( range. end - range. start - 1 ) / abs_step)
311
+ . to_usize ( )
312
+ . unwrap ( )
313
+ + 1 ;
314
+
343
315
// newlen will be 0 if step is overflowed
344
316
let newstep = newstep. to_isize ( ) . unwrap_or ( -1 ) ;
345
317
0 commit comments