Say I have the following functions from a C library:
type Foo = ptr object
proc newFoo(): Foo {.importc.}
proc freeFoo(f: Foo) {.importc.}
I'd like to wrap these to create an idiomatic Nim API with ref types.
type
Bar = ref BarObj
BarObj = object
data: Foo
proc `=destroy`(bar: var BarObj) =
freeFoo(bar.data)
proc newBar(): Bar =
new(result)
result.data = newFoo()
The trouble is, this introduces an additional layer of indirection, as Bar is a kind of pointer, and it contains a Foo which is also a pointer.
Is there some way to get the semantics of a ref type (where freeFoo is called when there are zero remaining references) without the inner pointer?
You need to avoid the ref if you need to avoid the indirection, but apart from that it's IMO an idiomatic API.
type
BarObj = object
data: Foo
refcount: ptr int
proc `=destroy`(bar: var BarObj) =
if bar.refcount[] == 0:
freeFoo(bar.data)
dealloc bar.refcount
else:
dec bar.refcount[]
proc `=copy`(dest: var BarObj; src: BarObj) =
inc src.refcount[]
`=destroy`(dest)
dest.data = src.data
dest.refcount = src.refcount
proc newBar(): BarObj =
result = BarObj(data: newFoo(), refcount: cast[ptr int](alloc0(sizeof(int)))
unless Foo already offers a refcount, you need to add one yourself and it needs a pointer indirection.