1- // export through slicable module, not slice.
1+ // export through sliceable module, not slice.
22use crate :: {
3- builtins:: { int:: PyInt , slice:: PySlice , PyIntRef } ,
3+ builtins:: { int:: PyInt , slice:: PySlice } ,
44 AsObject , PyObject , PyResult , VirtualMachine ,
55} ;
6+ use num_bigint:: BigInt ;
67use num_traits:: { Signed , ToPrimitive } ;
78use std:: ops:: Range ;
89
1213{
1314 type Item : Clone ;
1415 fn do_set ( & mut self , index : usize , value : Self :: Item ) ;
15- fn do_delele ( & mut self , index : usize ) ;
16+ fn do_delete ( & mut self , index : usize ) ;
1617 /// as CPython, length of range and items could be different, function must act like Vec::splice()
1718 fn do_set_range ( & mut self , range : Range < usize > , items : & [ Self :: Item ] ) ;
1819 fn do_delete_range ( & mut self , range : Range < usize > ) ;
3334 let pos = self
3435 . as_ref ( )
3536 . wrap_index ( index)
36- . ok_or_else ( || vm. new_index_error ( "assigment index out of range" . to_owned ( ) ) ) ?;
37+ . ok_or_else ( || vm. new_index_error ( "assignment index out of range" . to_owned ( ) ) ) ?;
3738 self . do_set ( pos, value) ;
3839 Ok ( ( ) )
3940 }
8990 let pos = self
9091 . as_ref ( )
9192 . wrap_index ( index)
92- . ok_or_else ( || vm. new_index_error ( "assigment index out of range" . to_owned ( ) ) ) ?;
93- self . do_delele ( pos) ;
93+ . ok_or_else ( || vm. new_index_error ( "assignment index out of range" . to_owned ( ) ) ) ?;
94+ self . do_delete ( pos) ;
9495 Ok ( ( ) )
9596 }
9697
@@ -118,7 +119,7 @@ impl<T: Clone> SliceableSequenceMutOp for Vec<T> {
118119 self [ index] = value;
119120 }
120121
121- fn do_delele ( & mut self , index : usize ) {
122+ fn do_delete ( & mut self , index : usize ) {
122123 self . remove ( index) ;
123124 }
124125
@@ -175,11 +176,11 @@ pub trait SliceableSequenceOp {
175176 fn len ( & self ) -> usize ;
176177
177178 fn wrap_index ( & self , p : isize ) -> Option < usize > {
178- wrap_index ( p , self . len ( ) )
179+ p . wrapped_at ( self . len ( ) )
179180 }
180181
181182 fn saturate_index ( & self , p : isize ) -> usize {
182- saturate_index ( p , self . len ( ) )
183+ p . saturated_at ( self . len ( ) )
183184 }
184185
185186 fn getitem_by_slice (
@@ -275,7 +276,7 @@ impl SequenceIndex {
275276 } else if let Some ( slice) = obj. payload :: < PySlice > ( ) {
276277 slice. to_saturated ( vm) . map ( Self :: Slice )
277278 } else if let Some ( i) = vm. to_index_opt ( obj. to_owned ( ) ) {
278- // TODO: __index__ for indice is no more supported?
279+ // TODO: __index__ for indices is no more supported?
279280 i?. try_to_primitive ( vm)
280281 . map_err ( |_| {
281282 vm. new_index_error ( "cannot fit 'int' into an index-sized integer" . to_owned ( ) )
@@ -291,50 +292,53 @@ impl SequenceIndex {
291292 }
292293}
293294
294- // Use PySliceableSequence::wrap_index for implementors
295- pub fn wrap_index ( p : isize , len : usize ) -> Option < usize > {
296- let neg = p. is_negative ( ) ;
297- let p = p. wrapping_abs ( ) as usize ;
298- if neg {
299- len. checked_sub ( p)
300- } else if p >= len {
301- None
302- } else {
303- Some ( p)
304- }
295+ pub trait SequenceIndexOp {
296+ // Saturate p in range [0, len] inclusive
297+ fn saturated_at ( & self , len : usize ) -> usize ;
298+ // Use PySliceableSequence::wrap_index for implementors
299+ fn wrapped_at ( & self , len : usize ) -> Option < usize > ;
305300}
306301
307- // Saturate p in range [0, len] inclusive
308- pub fn saturate_index ( p : isize , len : usize ) -> usize {
309- let len = len. to_isize ( ) . unwrap_or ( isize:: MAX ) ;
310- let mut p = p;
311- if p < 0 {
312- p += len;
302+ impl SequenceIndexOp for isize {
303+ fn saturated_at ( & self , len : usize ) -> usize {
304+ let len = len. to_isize ( ) . unwrap_or ( Self :: MAX ) ;
305+ let mut p = * self ;
313306 if p < 0 {
314- p = 0 ;
307+ p += len ;
315308 }
309+ p. clamp ( 0 , len) as usize
316310 }
317- if p > len {
318- p = len;
311+
312+ fn wrapped_at ( & self , len : usize ) -> Option < usize > {
313+ let neg = self . is_negative ( ) ;
314+ let p = self . unsigned_abs ( ) ;
315+ if neg {
316+ len. checked_sub ( p)
317+ } else if p >= len {
318+ None
319+ } else {
320+ Some ( p)
321+ }
319322 }
320- p as usize
321323}
322324
323- // Saturate p in range [0, len] inclusive
324- pub fn pyint_saturate_index ( p : PyIntRef , len : usize ) -> usize {
325- let bigint = p. as_bigint ( ) ;
326- if bigint. is_negative ( ) {
327- bigint
328- . abs ( )
329- . try_into ( )
330- . map_or ( 0 , |abs| len. saturating_sub ( abs) )
331- } else {
332- bigint. try_into ( ) . unwrap_or ( len)
325+ impl SequenceIndexOp for BigInt {
326+ fn saturated_at ( & self , len : usize ) -> usize {
327+ if self . is_negative ( ) {
328+ self . abs ( )
329+ . try_into ( )
330+ . map_or ( 0 , |abs| len. saturating_sub ( abs) )
331+ } else {
332+ self . try_into ( ) . unwrap_or ( len)
333+ }
334+ }
335+ fn wrapped_at ( & self , _len : usize ) -> Option < usize > {
336+ unimplemented ! ( "please add one once we need it" )
333337 }
334338}
335339
336340/// A saturated slice with values ranging in [isize::MIN, isize::MAX]. Used for
337- /// slicable sequences that require indices in the aforementioned range.
341+ /// sliceable sequences that require indices in the aforementioned range.
338342///
339343/// Invokes `__index__` on the PySliceRef during construction so as to separate the
340344/// transformation from PyObject into isize and the adjusting of the slice to a given
@@ -383,16 +387,16 @@ impl SaturatedSlice {
383387 let stop = if self . stop == -1 {
384388 len
385389 } else {
386- saturate_index ( self . stop . saturating_add ( 1 ) , len)
390+ self . stop . saturating_add ( 1 ) . saturated_at ( len)
387391 } ;
388392 let start = if self . start == -1 {
389393 len
390394 } else {
391- saturate_index ( self . start . saturating_add ( 1 ) , len)
395+ self . start . saturating_add ( 1 ) . saturated_at ( len)
392396 } ;
393397 stop..start
394398 } else {
395- saturate_index ( self . start , len) ..saturate_index ( self . stop , len)
399+ self . start . saturated_at ( len) ..self . stop . saturated_at ( len)
396400 } ;
397401
398402 let ( range, slice_len) = if range. start >= range. end {
0 commit comments