I've been experimenting with anything practically, so I'm here to ask...
**Minimal example following:**
import sequtils, sugar
type
ValueKind* = enum
StringV
ArrayV
NewlineV
Value {.acyclic.} = object
case kind*: ValueKind:
of StringV:
vs*: string
of ArrayV:
va*: ValueArray
cleaned: bool
of NewlineV:
discard
ValueArray = seq[Value]
proc cleanArray*(arr: Value): ptr ValueArray =
if arr.cleaned:
result = unsafeAddr arr.va
else:
var ret: ValueArray = arr.va.filter((x) => x.kind != NewlineV)
result = addr ret
when isMainModule:
var v1 = Value(kind: ArrayV, va: @[
Value(kind: StringV, vs: "hello"),
Value(kind: NewlineV),
Value(kind: StringV, vs: "world")
], cleaned: false)
var v2 = Value(kind: ArrayV, va: @[
Value(kind: StringV, vs: "hello"),
Value(kind: StringV, vs: "world")
], cleaned: true)
echo $(v1.va[0].vs)
var varr1 = cleanArray(v1)
var varr2 = cleanArray(v2)
echo "VARR1 -> len: " & $(varr1[].len) & "content: " & $(varr1[][0].vs)
& " " & $(varr1[][1].vs)
echo "VARR2 -> len: " & $(varr2[].len) & "content: " & $(varr2[][0].vs)
& " " & $(varr2[][1].vs)
Run
The idea here is (at least, what I _think_ I'm trying to achieve here) to avoid
copying `.va` (if not necessary, that is if it's "cleaned"). So, `cleanArray`,
either returns a pointer to `.va` or a pointer to a newly-created/filter `.va`.
Obviously, the problem in the latter case is that the pointer that is being
sent (for `varr1`) points to data that has been destroyed (there is an
`eqdestroy` right at the end of `cleanArray` and quite rightly so...)
Since `ptr` references, if I'm not mistaken, are not-managed pointers, I
thought of using `ref ValueArray` references for that. But then, how do I get a
reference to a `seq` this way? And no, I don't think something like the
following would work, since - although it does create a `ref ValueArray`, it
still includes a copy. All I want is pointer...
var v = new seq[Value]
v[] = someValue.va
Run