t9650.nim 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. discard """
  2. matrix: "--gc:arc"
  3. """
  4. import typetraits
  5. # bug #9650
  6. type
  7. SharedPtr*[T] = object
  8. val: ptr tuple[atomicCounter: int, value: T]
  9. Node*[T] = object
  10. value: T
  11. next: SharedPtr[Node[T]]
  12. ForwardList*[T] = object
  13. first: SharedPtr[Node[T]]
  14. proc `=destroy`*[T](p: var SharedPtr[T]) =
  15. if p.val != nil:
  16. let c = atomicDec(p.val[].atomicCounter)
  17. if c == 0:
  18. when not supportsCopyMem(T):
  19. `=destroy`(p.val[])
  20. dealloc(p.val)
  21. p.val = nil
  22. proc `=`*[T](dest: var SharedPtr[T], src: SharedPtr[T]) =
  23. if dest.val != src.val:
  24. if dest.val != nil:
  25. `=destroy`(dest)
  26. if src.val != nil:
  27. discard atomicInc(src.val[].atomicCounter)
  28. dest.val = src.val
  29. proc `=sink`*[T](dest: var SharedPtr[T], src: SharedPtr[T]) =
  30. if dest.val != nil and dest.val != src.val:
  31. `=destroy`(dest)
  32. dest.val = src.val
  33. proc newSharedPtr*[T](val: sink T): SharedPtr[T] =
  34. result = default(SharedPtr[T])
  35. result.val = cast[type(result.val)](alloc(sizeof(result.val[])))
  36. reset(result.val[])
  37. result.val.atomicCounter = 1
  38. result.val.value = val
  39. proc isNil*[T](p: SharedPtr[T]): bool =
  40. p.val == nil
  41. template `->`*[T](p: SharedPtr[T], name: untyped): untyped =
  42. p.val.value.name
  43. proc createNode[T](val: T): SharedPtr[ Node[T] ]=
  44. result = newSharedPtr(Node[T](value: val))
  45. proc push_front*[T](list: var ForwardList[T], val: T) =
  46. var newElem = createNode(val)
  47. newElem->next = list.first
  48. list.first = newElem
  49. proc pop_front*[T](list: var ForwardList[T]) =
  50. let head = list.first
  51. list.first = head->next
  52. proc toString*[T](list: ForwardList[T]): string =
  53. result = "["
  54. var head = list.first
  55. while not head.isNil:
  56. result &= $(head->value) & ", "
  57. head = head->next
  58. result &= ']'
  59. block:
  60. var x: ForwardList[int]
  61. x.push_front(1)
  62. x.push_front(2)
  63. x.push_front(3)
  64. doAssert toString(x) == "[3, 2, 1, ]"
  65. x.pop_front()
  66. x.pop_front()
  67. doAssert toString(x) == "[1, ]"
  68. x.pop_front()
  69. doAssert toString(x) == "[]"