How do you define a =copy hook for a distinct-cstring-type in nim?

88 Views Asked by At

For interacting with the GTK library I call some functions that hand me a c-string (char*) that my code owns going forward.

I want to have those strings in a custom distinct cstring type and define a =copy hook for those strings for use with nim's ARC/ORC system.

My minimal example looks likes this:

type OwnedGtkString* = distinct cstring

proc `=copy`*(dest: var OwnedGtkString, source: OwnedGtkString) =
  let areSameObject = pointer(source) == pointer(dest)
  if areSameObject:
    return
  
  `=destroy`(dest)
  wasMoved(dest)

  dest = source

let x: OwnedGtkString = "lala".OwnedGtkString
let y = x
echo x.pointer.repr
echo y.pointer.repr

Naturally this is naive implementation. This doesn't work because dest = source triggers the =copy hook again, making the entire thing recursive.

Now what else am I supposed to use here? copyMem would be an option if I could know how long the string is. Given that =copy is supposed to work for a whole breadth of different cstrings that seems non-feasible.

I also can't do simply assignments like this as that triggers the copy proc again.

So how is it supposed to be possible to define a copy-hook for a cstring?

1

There are 1 best solutions below

0
shirleyquirk On

i dont think an 'owned' cstring should be copyable, only sinkable.

but to sort out your infinite recursion issue: dest = OwnedGtkString(source.cstring) works as does `=copy`(dest.cstring,source.cstring)

but be aware you are copying pointers, and without ref counting you wont know when its safe to destroy them.

it's probably wiser to make your =copy {.error.} instead, and make this an =sink instead.