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