mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Extract saturate function.
This commit is contained in:
@@ -10,7 +10,7 @@ use crate::{
|
||||
protocol::{PyIterReturn, PyMappingMethods, PySequence, PySequenceMethods},
|
||||
recursion::ReprGuard,
|
||||
sequence::{MutObjectSequenceOp, SequenceExt, SequenceMutExt},
|
||||
sliceable::{SequenceIndex, SliceableSequenceMutOp, SliceableSequenceOp},
|
||||
sliceable::{pyint_saturate_index, SequenceIndex, SliceableSequenceMutOp, SliceableSequenceOp},
|
||||
types::{
|
||||
AsMapping, AsSequence, Comparable, Constructor, Hashable, Initializer, IterNext,
|
||||
IterNextIterable, Iterable, PyComparisonOp, Unconstructible, Unhashable,
|
||||
@@ -19,7 +19,6 @@ use crate::{
|
||||
vm::VirtualMachine,
|
||||
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult,
|
||||
};
|
||||
use num_traits::Signed;
|
||||
use std::{fmt, ops::DerefMut};
|
||||
|
||||
/// Built-in mutable sequence.
|
||||
@@ -277,54 +276,18 @@ impl PyList {
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<usize> {
|
||||
let len = self.len();
|
||||
let start: OptionalArg<PyIntRef> = match start {
|
||||
OptionalArg::Missing => OptionalArg::Missing,
|
||||
OptionalArg::Present(obj) => OptionalArg::Present(obj.try_into_value(vm)?),
|
||||
};
|
||||
let stop: OptionalArg<PyIntRef> = match stop {
|
||||
OptionalArg::Missing => OptionalArg::Missing,
|
||||
OptionalArg::Present(obj) => OptionalArg::Present(obj.try_into_value(vm)?),
|
||||
};
|
||||
let start: usize = match start {
|
||||
OptionalArg::Missing => 0,
|
||||
OptionalArg::Present(obj) => {
|
||||
let bigint = obj.as_bigint();
|
||||
if bigint.is_negative() {
|
||||
let idx: Result<usize, _> = bigint.abs().try_into();
|
||||
match idx {
|
||||
Ok(abs) => {
|
||||
if abs >= len {
|
||||
0
|
||||
} else {
|
||||
len - abs
|
||||
}
|
||||
}
|
||||
Err(_) => 0,
|
||||
}
|
||||
} else {
|
||||
bigint.try_into().unwrap_or(len)
|
||||
}
|
||||
let int: PyIntRef = obj.try_into_value(vm)?;
|
||||
pyint_saturate_index(int, len)
|
||||
}
|
||||
};
|
||||
let stop: usize = match stop {
|
||||
OptionalArg::Missing => len,
|
||||
OptionalArg::Present(obj) => {
|
||||
let bigint = obj.as_bigint();
|
||||
if bigint.is_negative() {
|
||||
let idx: Result<usize, _> = bigint.abs().try_into();
|
||||
match idx {
|
||||
Ok(abs) => {
|
||||
if abs >= len {
|
||||
0
|
||||
} else {
|
||||
len - abs
|
||||
}
|
||||
}
|
||||
Err(_) => 0,
|
||||
}
|
||||
} else {
|
||||
bigint.try_into().unwrap_or(len)
|
||||
}
|
||||
let int: PyIntRef = obj.try_into_value(vm)?;
|
||||
pyint_saturate_index(int, len)
|
||||
}
|
||||
};
|
||||
let index = self.mut_index_range(vm, &needle, start..stop)?;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// export through slicable module, not slice.
|
||||
use crate::{
|
||||
builtins::{int::PyInt, slice::PySlice},
|
||||
builtins::{int::PyInt, slice::PySlice, PyIntRef},
|
||||
AsObject, PyObject, PyResult, VirtualMachine,
|
||||
};
|
||||
use num_traits::{Signed, ToPrimitive};
|
||||
@@ -320,6 +320,19 @@ pub fn saturate_index(p: isize, len: usize) -> usize {
|
||||
p as usize
|
||||
}
|
||||
|
||||
// Saturate p in range [0, len] inclusive
|
||||
pub fn pyint_saturate_index(p: PyIntRef, len: usize) -> usize {
|
||||
let bigint = p.as_bigint();
|
||||
if bigint.is_negative() {
|
||||
bigint
|
||||
.abs()
|
||||
.try_into()
|
||||
.map_or(0, |abs| len.saturating_sub(abs))
|
||||
} else {
|
||||
bigint.try_into().unwrap_or(len)
|
||||
}
|
||||
}
|
||||
|
||||
/// A saturated slice with values ranging in [isize::MIN, isize::MAX]. Used for
|
||||
/// slicable sequences that require indices in the aforementioned range.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user