3
3
4
4
import ./ builtins/ pyslice
5
5
6
- import std/ enumerate
7
-
8
6
template loopDown (a, b; step) =
9
7
# # .. also reverse to avoid indices changing
10
8
for i in countdown (min (len (ms)- 1 , a), max (0 , b), step):
@@ -25,11 +23,42 @@ template genDelItem*(Arr){.dirty.} =
25
23
else :
26
24
loopDown (b, indices.start, indices.step)
27
25
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]
28
40
29
41
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
33
62
34
63
template genGenericSetItem * (Arr, Arr2){.dirty .} =
35
64
bind bodySetItem
0 commit comments