blob: a8182db68c7be11ac06268aef794879d943aa17f (
plain) (
tree)
|
|
discard """
matrix: "--gc:arc"
"""
import typetraits
# bug #9650
type
SharedPtr*[T] = object
val: ptr tuple[atomicCounter: int, value: T]
Node*[T] = object
value: T
next: SharedPtr[Node[T]]
ForwardList*[T] = object
first: SharedPtr[Node[T]]
proc `=destroy`*[T](p: var SharedPtr[T]) =
if p.val != nil:
let c = atomicDec(p.val[].atomicCounter)
if c == 0:
when not supportsCopyMem(T):
`=destroy`(p.val[])
dealloc(p.val)
p.val = nil
proc `=`*[T](dest: var SharedPtr[T], src: SharedPtr[T]) =
if dest.val != src.val:
if dest.val != nil:
`=destroy`(dest)
if src.val != nil:
discard atomicInc(src.val[].atomicCounter)
dest.val = src.val
proc `=sink`*[T](dest: var SharedPtr[T], src: SharedPtr[T]) =
if dest.val != nil and dest.val != src.val:
`=destroy`(dest)
dest.val = src.val
proc newSharedPtr*[T](val: sink T): SharedPtr[T] =
result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
reset(result.val[])
result.val.atomicCounter = 1
result.val.value = val
proc isNil*[T](p: SharedPtr[T]): bool =
p.val == nil
template `->`*[T](p: SharedPtr[T], name: untyped): untyped =
p.val.value.name
proc createNode[T](val: T): SharedPtr[ Node[T] ]=
result = newSharedPtr(Node[T](value: val))
proc push_front*[T](list: var ForwardList[T], val: T) =
var newElem = createNode(val)
newElem->next = list.first
list.first = newElem
proc pop_front*[T](list: var ForwardList[T]) =
let head = list.first
list.first = head->next
proc toString*[T](list: ForwardList[T]): string =
result = "["
var head = list.first
while not head.isNil:
result &= $(head->value) & ", "
head = head->next
result &= ']'
block:
var x: ForwardList[int]
x.push_front(1)
x.push_front(2)
x.push_front(3)
doAssert toString(x) == "[3, 2, 1, ]"
x.pop_front()
x.pop_front()
doAssert toString(x) == "[1, ]"
x.pop_front()
doAssert toString(x) == "[]"
|