type
Alternative_Seq*[T] = object
length*: int
, capacity*: int
data*: ptr UncheckedArray[T]
proc `=destroy`*[T](x: Alternative_Seq[T]) =
if x.data != nil:
for i in 0..<x.len: `=destroy`(x.data[i])
dealloc(x.data)
proc `=trace`[T](x: var Alternative_Seq[T]; env: pointer) =
# `=trace` allows the cycle collector `--mm:orc`
# to understand how to trace the object graph.
if x.data != nil:
for i in 0..<x.len: `=trace`(x.data[i], env)
proc `=copy`*[T](a: var Alternative_Seq[T]; b: Alternative_Seq[T]) =
# do nothing for self-assignments:
if a.data == b.data: return
`=destroy`(a)
wasMoved(a)
a.len = b.len
a.cap = b.cap
if b.data != nil:
a.data = cast[typeof(a.data)](alloc(a.cap * sizeof(T)))
for i in 0..<a.len:
a.data[i] = b.data[i]
proc `=dup`*[T](a: Alternative_Seq[T]): Alternative_Seq[T] {.nodestroy.} =
# an optimized version of `=wasMoved(tmp); `=copy(tmp, src)`
# usually present if a custom `=copy` hook is overridden
result.len = a.len
result.cap = a.cap
if a.data != nil:
result.data = cast[typeof(result.data)](alloc(result.cap * sizeof(T)))
for i in 0..<result.len:
result.data[i] = `=dup`(a.data[i])
proc `=sink`*[T](a: var Alternative_Seq[T]; b: Alternative_Seq[T]) =
# move assignment, optional.
# Compiler is using `=destroy` and `copyMem` when not provided
`=destroy`(a)
wasMoved(a)
a.len = b.len
a.cap = b.cap
a.data = b.data
proc add*[T](x: var Alternative_Seq[T]; y: sink T) =
if x.len >= x.cap:
x.cap = max(x.len + 1, x.cap * 2)
x.data = cast[typeof(x.data)](realloc(x.data, x.cap * sizeof(T)))
x.data[x.len] = y
inc x.len
proc `[]`*[T](x: Alternative_Seq[T]; i: Natural): lent T =
assert i < x.len
x.data[i]
proc `[]=`*[T](x: var Alternative_Seq[T]; i: Natural; y: sink T) =
assert i < x.len
x.data[i] = y
proc an_alternative_seq*[T](elems: varargs[T]): Alternative_Seq[T] =
result.cap = elems.len
result.len = elems.len
result.data = cast[typeof(result.data)](alloc(result.cap * sizeof(T)))
for i in 0..<result.len: result.data[i] = elems[i]
proc len*[T](x: Alternative_Seq[T]): int {.inline.} = x.len