Skip to content

Commit cd9ed64

Browse files
committed
fixup! fix(list): slice with negative value causes RangeDefect;
fix setitem discarded longer values
1 parent 21b7f79 commit cd9ed64

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

src/pylib/mutSeqSliceOp.nim

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
import ./builtins/pyslice
55

6-
import std/enumerate
7-
86
template loopDown(a, b; step) =
97
## .. also reverse to avoid indices changing
108
for i in countdown(min(len(ms)-1, a), max(0, b), step):
@@ -25,11 +23,42 @@ template genDelItem*(Arr){.dirty.} =
2523
else:
2624
loopDown(b, indices.start, indices.step)
2725

26+
template moveItems(ms, dest, frm, n) =
27+
## .. also reverse to avoid indices changing
28+
when declared(moveMem):
29+
when compiles(addr ms[dest]):
30+
moveMem(addr ms[dest], addr ms[frm], n*sizeof(ms[0]))
31+
else:
32+
moveMem(ms.getPtr dest, ms.getPtr frm, n*sizeof(ms[0]))
33+
else:
34+
if frm > dest:
35+
for i in 0..<n:
36+
ms[dest+i] = ms[frm+i]
37+
else:
38+
for i in countdown(n-1, 0):
39+
ms[dest+i] = ms[frm+i]
2840

2941
template bodySetItem*(Arr){.dirty.} =
30-
bind enumerate
31-
for i, idx in enumerate(indices.b .. indices.a):
32-
ms[idx] = o[i]
42+
bind moveItems
43+
var ilow = indices.a
44+
let ihigh = indices.b + 1
45+
let norig = ihigh - ilow
46+
assert norig >= 0
47+
let n = o.len
48+
let d = n - norig
49+
let le = ms.len
50+
if le + d == 0:
51+
ms.clear()
52+
return
53+
if d < 0: # Delete -d items
54+
moveItems(ms, ihigh+d, ihigh, le-ihigh)
55+
ms.setLen le+d
56+
elif d > 0: # Insert d items
57+
ms.setLen le+d
58+
moveItems(ms, ihigh+d, ihigh, le-ihigh)
59+
for k in 0..<n:
60+
ms[ilow] = o[k]
61+
ilow.inc
3362

3463
template genGenericSetItem*(Arr, Arr2){.dirty.} =
3564
bind bodySetItem

0 commit comments

Comments
 (0)