> No, ref is not a double indirection.
@Araq, I think I see how ref might be implemented:
type
RefObj[T] = object # non shared version
cntnts: T
refcnt: int
ref[T] = ptr RefObj[T]
refshared[T] = distinct ref[T] # just distinct cases of the same thing...
refowned[T] = distinct ref[T] # they should all be castable among them...
refownedshared[T] = distinct ref[T] # behaviour below depends on type...
Run
However, in order to do what I suggested to handle pointer fields pointing to
the same thing, the "hooks" would need to be expanded to handle any type and
not be limited to only objects as =destroy and = are now (I don't think we have
=move yet, right?). However, that currently works for arbitrary functions, I
don't see why the standard "hooks" can't be expanded:
# a byte copy without destructor/move/assignment semantics...
proc copy[T](dst: var T; src: T) {.inline.} =
copyMem(dst.unsafeAddr, src.unsafeAddr, T.sizeof)
# a byte swap without destructor/move/assignment semantics...
proc swap[T](dst, src: var T) {.inline.} =
var tmp: T; copy(tmp, dst); copy(dst, src); copy(src, tmp)
# defaults in system to be overridden for special types as necessary...
proc `=destroy`[T: not object](x: var T) = discard
proc `=destroy`[T: object](x: var T) = discard
proc `=destroy`[T](xp: ptr T) =
if xp == nil: return # nothing to destroy
xp[].`=destroy`; xp.dealloc; (xp.unsafeAddr)[] = nil
proc `=destroy`[T](xr: var ref T) =
if xr == nil: return # nothing to destroy
if xr.refcnt >1: xr.refcnt.dec
else:
xr[].`=destroy` # destroy contents recursively if needed
xr.dealloc; (xr.unsafeAddr)[] = nil
proc `=destroy`[T](xr: var refowned T) =
if xr == nil: return # nothing to destroy
assert xr.refcnt == 1
xr[].`=destroy` # destroy contents recursively if needed
xr.dealloc; (xr.unsafeAddr)[] = nil
# and so on for the special cases for refshared and refownedshared..
# and also so on for the `=` and `=move` overrides
# and also add overrides for the cases for the `[]` and `[]=` for atomic
and non-atomic access
Run
This is not indirectly linked and would seem to cover all the cases, including
allowing more than one field references to the same object.