diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2020-03-17 15:33:08 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-17 15:33:08 -0700 |
| commit | 4603c6ddd7aaccc5674db135fe3951e475ea05d8 (patch) | |
| tree | 238adb6865105638b47fa6a21b4be5d8afbf74df /py/objslice.c | |
| parent | 9453e10c57deee12f895466d872e3e9198c73f7d (diff) | |
| parent | 38a718ff5558c2286172091615aaeb2ded5f70f5 (diff) | |
Merge pull request #2711 from jepler/update-ulab5.1.0-rc.05.1.0
update ulab
Diffstat (limited to 'py/objslice.c')
| -rw-r--r-- | py/objslice.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/py/objslice.c b/py/objslice.c index 5a15be55a..cbbee326e 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -152,6 +152,71 @@ mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) { return MP_OBJ_FROM_PTR(o); } +// Return the real index and step values for a slice when applied to a sequence of +// the given length, resolving missing components, negative values and values off +// the end of the sequence. +void mp_obj_slice_indices(mp_obj_t self_in, mp_int_t length, mp_bound_slice_t *result) { + mp_obj_slice_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t start, stop, step; + + if (self->step == mp_const_none) { + step = 1; + } else { + step = mp_obj_get_int(self->step); + if (step == 0) { + mp_raise_ValueError(translate("slice step cannot be zero")); + } + } + + if (step > 0) { + // Positive step + if (self->start == mp_const_none) { + start = 0; + } else { + start = mp_obj_get_int(self->start); + if (start < 0) { + start += length; + } + start = MIN(length, MAX(start, 0)); + } + + if (self->stop == mp_const_none) { + stop = length; + } else { + stop = mp_obj_get_int(self->stop); + if (stop < 0) { + stop += length; + } + stop = MIN(length, MAX(stop, 0)); + } + } else { + // Negative step + if (self->start == mp_const_none) { + start = length - 1; + } else { + start = mp_obj_get_int(self->start); + if (start < 0) { + start += length; + } + start = MIN(length - 1, MAX(start, -1)); + } + + if (self->stop == mp_const_none) { + stop = -1; + } else { + stop = mp_obj_get_int(self->stop); + if (stop < 0) { + stop += length; + } + stop = MIN(length - 1, MAX(stop, -1)); + } + } + + result->start = start; + result->stop = stop; + result->step = step; +} + #if MICROPY_PY_BUILTINS_SLICE_ATTRS STATIC mp_obj_t slice_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { |
