ArrRef and SliceMem: Add concat
, suport for backward indexes, and fix $
.
This commit is contained in:
parent
d784dd3a52
commit
e759f25519
|
@ -48,6 +48,12 @@ proc `[]=`*[T](a: ArrRef[T], i: Natural, v: T) =
|
|||
raise newException(RangeDefect, &"index out of range: {i} >= {a.len}")
|
||||
a.arr[i] = v
|
||||
|
||||
template `[]`*[T](a: ArrRef[T], i: BackwardsIndex): T =
|
||||
a[a.len - i.int]
|
||||
|
||||
template `[]=`*[T](a: ArrRef[T], i: BackwardsIndex, v: T) =
|
||||
a[a.len - i.int] = v
|
||||
|
||||
template toPointer*[T](a: ArrRef[T]): pointer = a.arr[0].addr
|
||||
|
||||
iterator items*[T](a: ArrRef[T]): T =
|
||||
|
@ -68,7 +74,7 @@ iterator mpairs*[T](a: ArrRef[T]): tuple[key: int, val: var T] =
|
|||
|
||||
proc `$`*[T](a: ArrRef[T]): string =
|
||||
result = "ArrRef(["
|
||||
if a.endp != a.arr:
|
||||
if a.byte_len >= sizeof(T):
|
||||
let hi = a.high
|
||||
for i in 0 ..< hi:
|
||||
result &= $a[i] & ", "
|
||||
|
@ -78,21 +84,6 @@ proc `$`*[T](a: ArrRef[T]): string =
|
|||
template to*[T](a: ArrRef[T], U: untyped): untyped =
|
||||
cast[ArrRef[U]](a)
|
||||
|
||||
# proc setCap*[T](a: var ArrRef[T], size: Natural) =
|
||||
# let n = newArrRef[T](size)
|
||||
# copyMem(n[0].addr, a[0].addr, min(size, a.len) * sizeof(T))
|
||||
# a = n
|
||||
|
||||
# proc setGrow*[T](a: var ArrRef[T], i: Natural, v: T) =
|
||||
# let p = cast[int](a) +% header_size +% sizeof(T) * i
|
||||
# if p +% sizeof(T) > cast[int](a.endp):
|
||||
# var cap = max(1, a.len)
|
||||
# while i >= cap:
|
||||
# if cap < 65535: cap *= 2
|
||||
# else: cap = (cap * 3) div 2
|
||||
# a.setCap cap
|
||||
# cast[ptr T](p)[] = v
|
||||
|
||||
proc fill*[T](a: ArrRef[T], v: T) =
|
||||
for i in a.low .. a.high: a[i] = v
|
||||
|
||||
|
@ -108,11 +99,14 @@ proc newArrRefWith*[T](size: Natural, v: T): ArrRef[T] =
|
|||
result.arr_ptr = result.arr[0].addr
|
||||
for i in result.low .. result.high: result[i] = v
|
||||
|
||||
proc newArrRef*[T](s: seq[T] | ArrRef[T]): ArrRef[T] =
|
||||
proc newArrRef*[T](s: seq[T] | ArrRef[T] | openArray[T]): ArrRef[T] =
|
||||
result = newArrRef[T](s.len)
|
||||
if s.len != 0:
|
||||
copyMem(result.arr.addr, s[0].addr, s.len * sizeof(T))
|
||||
|
||||
template newArrRef*[T](s: string): ArrRef[T] =
|
||||
newArrRef[byte](s.toOpenArrayByte(0, s.high)).to(T)
|
||||
|
||||
proc newArrRef*[T; U: not T](s: seq[U]): ArrRef[T] =
|
||||
result = newArrRef[T](s.len)
|
||||
for i,v in s: result[i] = v.T
|
||||
|
@ -139,3 +133,22 @@ proc hash*[T](arr: ArrRef[T]): Hash =
|
|||
template `[]`*[T](a: ArrRef[T], s: Slice[int]): var SliceMem[T] =
|
||||
toSliceMem(a, s)
|
||||
|
||||
template concatImpl(arrs: untyped) =
|
||||
var total = 0
|
||||
for a in arrs:
|
||||
total += a.len
|
||||
result = newArrRef[T](total)
|
||||
var offset = 0
|
||||
for a in arrs:
|
||||
copyMem(result[offset].addr, a.toPointer, a.len * sizeof(T))
|
||||
offset += a.len
|
||||
|
||||
proc concat*[T](arrs: varargs[ArrRef[T]]): ArrRef[T] =
|
||||
concatImpl(arrs)
|
||||
|
||||
proc concat*[T](arrs: seq[ArrRef[T]]): ArrRef[T] =
|
||||
concatImpl(arrs)
|
||||
|
||||
template `&`*[T,U](a: ArrRef[T], b: ArrRef[U]): ArrRef[T] =
|
||||
concat(a, b.to(T))
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ proc `=destroy`(s: var CustomDestructor) =
|
|||
template toInt(p: pointer): int = cast[int](p)
|
||||
# template toPointer(i: int): pointer = cast[pointer](p)
|
||||
|
||||
template toPointer*(s: SliceMem): pointer =
|
||||
s.data.pointer
|
||||
|
||||
proc newSliceMem*[T, U](container: sink U; p: pointer, byte_len: int): SliceMem[T] =
|
||||
## Create a SliceMem from a container, a pointer, and a length in bytes.
|
||||
result = SliceMem[T](
|
||||
|
@ -67,6 +70,18 @@ proc newSliceMem*[T, U](container: sink U; first, last: pointer): SliceMem[T] =
|
|||
),
|
||||
)
|
||||
|
||||
proc newSliceMem*[T](size: int): SliceMem[T] =
|
||||
## Create a SliceMem from new memory, similar to ArrRef[T].
|
||||
var r: ref byte
|
||||
unsafeNew(r, size * sizeof(T))
|
||||
result = SliceMem[T](
|
||||
data: cast[ptr UncheckedArray[T]](r),
|
||||
byte_len: size * sizeof(T),
|
||||
destroy_ref: (ref CustomDestructor)(destroy: proc()=
|
||||
discard r
|
||||
),
|
||||
)
|
||||
|
||||
macro noMove(e: untyped): untyped =
|
||||
if e.kind == nnkCommand and e[0].repr == "move": e[1]
|
||||
else: e
|
||||
|
@ -97,18 +112,33 @@ template low*[T](s: SliceMem[T]): Natural = 0
|
|||
|
||||
template high*[T](s: SliceMem[T]): int = s.len - 1
|
||||
|
||||
template `[]`*[T](s: SliceMem[T], i: Natural): var T =
|
||||
proc `[]`*[T](s: SliceMem[T], i: Natural): var T {.inline.} =
|
||||
when compileOption("rangechecks"):
|
||||
if i >= s.len:
|
||||
raise newException(RangeDefect, &"index out of range: {i} >= {s.len}")
|
||||
s.data[i]
|
||||
|
||||
proc `[]=`*[T](s: SliceMem[T], i: Natural, v: T) =
|
||||
proc `[]=`*[T](s: SliceMem[T], i: Natural, v: T) {.inline.} =
|
||||
when compileOption("rangechecks"):
|
||||
if i >= s.len:
|
||||
raise newException(RangeDefect, &"index out of range: {i} >= {s.len}")
|
||||
s.data[i] = v
|
||||
|
||||
template `[]`*[T](s: SliceMem[T], i: BackwardsIndex): T =
|
||||
s[s.len - i.int]
|
||||
|
||||
template `[]=`*[T](s: SliceMem[T], i: BackwardsIndex, v: T) =
|
||||
s[s.len - i.int] = v
|
||||
|
||||
template `[]`*[T](s: SliceMem[T], i: BackwardsIndex): T =
|
||||
s[s.len - i.int]
|
||||
|
||||
template `[]=`*[T](s: SliceMem[T], i: BackwardsIndex, v: T) =
|
||||
s[s.len - i.int] = v
|
||||
|
||||
template `[]`*[T](a: SliceMem[T], s: Slice[int]): var SliceMem[T] =
|
||||
toSliceMem(a, s)
|
||||
|
||||
iterator items*[T](s: SliceMem[T]): T =
|
||||
for i in 0 ..< s.len:
|
||||
yield s.data[i]
|
||||
|
@ -146,3 +176,28 @@ template toOpenArrayByte*(s: SliceMem): untyped =
|
|||
|
||||
template to*[T](s: SliceMem, typ: typedesc[T]): SliceMem[T] =
|
||||
cast[SliceMem[T]](s)
|
||||
|
||||
template to*[T](s: seq[SliceMem], typ: typedesc[T]): seq[SliceMem[T]] =
|
||||
var s2 = newSeqOfCap[SliceMem[T]](s.len)
|
||||
for slice in s:
|
||||
s2.add cast[SliceMem[T]](slice)
|
||||
s2
|
||||
|
||||
template concatImpl(slices: untyped) =
|
||||
var total = 0
|
||||
for s in slices:
|
||||
total += s.len
|
||||
result = newSliceMem[T](total)
|
||||
var offset = 0
|
||||
for s in slices:
|
||||
copyMem(result[offset].addr, s.data, s.len * sizeof(T))
|
||||
offset += s.len
|
||||
|
||||
proc concat*[T](slices: varargs[SliceMem[T]]): SliceMem[T] =
|
||||
concatImpl(slices)
|
||||
|
||||
proc concat*[T](slices: seq[SliceMem[T]]): SliceMem[T] =
|
||||
concatImpl(slices)
|
||||
|
||||
template `&`*[T,U](a: SliceMem[T], b: SliceMem[U]): SliceMem[T] =
|
||||
concat(a, b.to(T))
|
||||
|
|
Loading…
Reference in a new issue