t9650.nim 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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.val = cast[type(result.val)](alloc(sizeof(result.val[])))
  35. reset(result.val[])
  36. result.val.atomicCounter = 1
  37. result.val.value = val
  38. proc isNil*[T](p: SharedPtr[T]): bool =
  39. p.val == nil
  40. template `->`*[T](p: SharedPtr[T], name: untyped): untyped =
  41. p.val.value.name
  42. proc createNode[T](val: T): SharedPtr[ Node[T] ]=
  43. result = newSharedPtr(Node[T](value: val))
  44. proc push_front*[T](list: var ForwardList[T], val: T) =
  45. var newElem = createNode(val)
  46. newElem->next = list.first
  47. list.first = newElem
  48. proc pop_front*[T](list: var ForwardList[T]) =
  49. let head = list.first
  50. list.first = head->next
  51. proc toString*[T](list: ForwardList[T]): string =
  52. result = "["
  53. var head = list.first
  54. while not head.isNil:
  55. result &= $(head->value) & ", "
  56. head = head->next
  57. result &= ']'
  58. block:
  59. var x: ForwardList[int]
  60. x.push_front(1)
  61. x.push_front(2)
  62. x.push_front(3)
  63. doAssert toString(x) == "[3, 2, 1, ]"
  64. x.pop_front()
  65. x.pop_front()
  66. doAssert toString(x) == "[1, ]"
  67. x.pop_front()
  68. doAssert toString(x) == "[]"