Skip to content

Commit 763147c

Browse files
authored
arraybuf: new constructor (#236)
* arraybuf: new constructor also add a block to avoid symbol leaks * speed up for same length
1 parent b7b5969 commit 763147c

File tree

2 files changed

+42
-10
lines changed

2 files changed

+42
-10
lines changed

stew/arraybuf.nim

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,22 @@ template len*(b: ArrayBuf): int =
4848
int(b.n)
4949

5050
template setLen*(b: var ArrayBuf, newLenParam: int) =
51-
newLenParam.evalOnceAs(newLen)
52-
let nl = typeof(b.n)(newLen)
53-
for i in newLen ..< b.len():
54-
reset(b.buf[i]) # reset cleared items when shrinking
55-
b.n = nl
51+
block:
52+
newLenParam.evalOnceAs(newLen)
53+
let nl = typeof(b.n)(newLen)
54+
for i in newLen ..< b.len():
55+
reset(b.buf[i]) # reset cleared items when shrinking
56+
b.n = nl
5657

5758
template data*(bParam: ArrayBuf): openArray =
58-
bParam.evalOnceAs(b)
59-
b.buf.toOpenArray(0, b.len() - 1)
59+
block:
60+
bParam.evalOnceAs(b)
61+
b.buf.toOpenArray(0, b.len() - 1)
6062

6163
template data*(bParam: var ArrayBuf): var openArray =
62-
bParam.evalOnceAs(b)
63-
b.buf.toOpenArray(0, b.len() - 1)
64+
block:
65+
bParam.evalOnceAs(b)
66+
b.buf.toOpenArray(0, b.len() - 1)
6467

6568
iterator items*[N, T](b: ArrayBuf[N, T]): lent T =
6669
for i in 0 ..< b.len:
@@ -92,6 +95,22 @@ template `==`*(a, b: ArrayBuf): bool =
9295
template `<`*(a, b: ArrayBuf): bool =
9396
a.data() < b.data()
9497

98+
template initCopyFrom*[N, T](
99+
_: type ArrayBuf[N, T], data: openArray[T]
100+
): ArrayBuf[N, T] =
101+
var v: ArrayBuf[N, T]
102+
v.n = typeof(v.n)(v.buf.copyFrom(data))
103+
v
104+
105+
template initCopyFrom*[N, T](
106+
_: type ArrayBuf[N, T], data: array[N, T]
107+
): ArrayBuf[N, T] =
108+
# Shortcut version that avoids zeroMem on matching lengths
109+
ArrayBuf[N, T](
110+
buf: data,
111+
n: N
112+
)
113+
95114
template add*[N, T](b: var ArrayBuf[N, T], v: T) =
96115
## Adds items up to capacity then drops the rest
97116
# TODO `b` is evaluated multiple times but since it's a `var` this should
@@ -112,4 +131,4 @@ template pop*[N, T](b: var ArrayBuf[N, T]): T =
112131
# _hopefully_ be fine..
113132
assert b.n > 0, "pop from empty ArrayBuf"
114133
b.n -= 1
115-
move(b.buf[b.n])
134+
move(b.buf[b.n])

tests/test_arraybuf.nim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,16 @@ suite "ArrayBuf":
5656
v.len == 1
5757
v.setLen(2)
5858
doAssert v.data() == [byte 1, 0]
59+
60+
test "construction":
61+
let
62+
a0 = ArrayBuf[4, byte].initCopyFrom([])
63+
a2 = ArrayBuf[2, byte].initCopyFrom([byte 2, 3, 4, 5])
64+
a3 = ArrayBuf[5, byte].initCopyFrom([byte 2, 3, 4])
65+
a5 = ArrayBuf[5, byte].initCopyFrom([byte 2, 3])
66+
67+
check:
68+
a0.len == 0
69+
a2.data() == [byte 2, 3]
70+
a3.data() == [byte 2, 3, 4]
71+
a5.data() == [byte 2, 3]

0 commit comments

Comments
 (0)