objlist: Implement growing slice assignment.
This means that complete slice operations are supported for lists (but not for bytearray's and array.array's).
This commit is contained in:
parent
69d081a7cf
commit
2705f4c782
5
py/obj.h
5
py/obj.h
@ -578,3 +578,8 @@ mp_obj_t mp_seq_count_obj(const mp_obj_t *items, uint len, mp_obj_t value);
|
|||||||
memcpy(dest + beg, slice, slice_len * sizeof(item_t)); \
|
memcpy(dest + beg, slice, slice_len * sizeof(item_t)); \
|
||||||
/*printf("memcpy(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));*/ \
|
/*printf("memcpy(%p, %p, %d)\n", dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));*/ \
|
||||||
memcpy(dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));
|
memcpy(dest + (beg + slice_len), dest + end, (dest_len - end) * sizeof(item_t));
|
||||||
|
|
||||||
|
#define mp_seq_replace_slice_grow_inplace(dest, dest_len, beg, end, slice, slice_len, len_adj, item_t) \
|
||||||
|
/*printf("memmove(%p, %p, %d)\n", dest + beg + len_adj, dest + beg, (dest_len - beg) * sizeof(item_t));*/ \
|
||||||
|
memmove(dest + beg + len_adj, dest + beg, (dest_len - beg) * sizeof(item_t)); \
|
||||||
|
memcpy(dest + beg, slice, slice_len * sizeof(item_t));
|
||||||
|
19
py/objlist.c
19
py/objlist.c
@ -199,12 +199,21 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|||||||
}
|
}
|
||||||
int len_adj = slice->len - (stop - start);
|
int len_adj = slice->len - (stop - start);
|
||||||
//printf("Len adj: %d\n", len_adj);
|
//printf("Len adj: %d\n", len_adj);
|
||||||
assert(len_adj <= 0);
|
if (len_adj > 0) {
|
||||||
mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t);
|
if (self->len + len_adj > self->alloc) {
|
||||||
// Clear "freed" elements at the end of list
|
// TODO: Might optimize memory copies here by checking if block can
|
||||||
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
|
// be grown inplace or not
|
||||||
|
self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + len_adj);
|
||||||
|
self->alloc = self->len + len_adj;
|
||||||
|
}
|
||||||
|
mp_seq_replace_slice_grow_inplace(self->items, self->len, start, stop, slice->items, slice->len, len_adj, mp_obj_t);
|
||||||
|
} else {
|
||||||
|
mp_seq_replace_slice_no_grow(self->items, self->len, start, stop, slice->items, slice->len, mp_obj_t);
|
||||||
|
// Clear "freed" elements at the end of list
|
||||||
|
mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items));
|
||||||
|
// TODO: apply allocation policy re: alloc_size
|
||||||
|
}
|
||||||
self->len += len_adj;
|
self->len += len_adj;
|
||||||
// TODO: apply allocation policy re: alloc_size
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
28
tests/basics/list_slice_assign_grow.py
Normal file
28
tests/basics/list_slice_assign_grow.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
x = list(range(2))
|
||||||
|
|
||||||
|
l = list(x)
|
||||||
|
l[0:0] = [10]
|
||||||
|
print(l)
|
||||||
|
l = list(x)
|
||||||
|
l[:0] = [10, 20]
|
||||||
|
print(l)
|
||||||
|
l = list(x)
|
||||||
|
l[0:0] = [10, 20, 30, 40]
|
||||||
|
print(l)
|
||||||
|
|
||||||
|
l = list(x)
|
||||||
|
l[1:1] = [10, 20, 30, 40]
|
||||||
|
print(l)
|
||||||
|
|
||||||
|
l = list(x)
|
||||||
|
l[2:] = [10, 20, 30, 40]
|
||||||
|
print(l)
|
||||||
|
|
||||||
|
# Weird cases
|
||||||
|
l = list(x)
|
||||||
|
l[1:0] = [10, 20, 30, 40]
|
||||||
|
print(l)
|
||||||
|
|
||||||
|
l = list(x)
|
||||||
|
l[100:100] = [10, 20, 30, 40]
|
||||||
|
print(l)
|
Loading…
Reference in New Issue
Block a user