diff options
author | Arne Döring <arne.doering@gmx.net> | 2019-03-18 11:37:09 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-03-18 11:37:09 +0100 |
commit | 97c3b113a52dc96f08a898d3e5ae886bce529bc3 (patch) | |
tree | db04a2419b19deea272e28ee59dd44beb365dbc2 /tests/destructor | |
parent | 5661a8303ca90822b22ebb59a45e31b309c59c19 (diff) | |
download | Nim-97c3b113a52dc96f08a898d3e5ae886bce529bc3.tar.gz |
Size ptr tuple (#10846)
* fixes #10117 * Add support for recursive tuples * detect in generics
Diffstat (limited to 'tests/destructor')
-rw-r--r-- | tests/destructor/smart_ptr.nim | 49 | ||||
-rw-r--r-- | tests/destructor/trecursive.nim | 34 |
2 files changed, 83 insertions, 0 deletions
diff --git a/tests/destructor/smart_ptr.nim b/tests/destructor/smart_ptr.nim new file mode 100644 index 000000000..7c3141d22 --- /dev/null +++ b/tests/destructor/smart_ptr.nim @@ -0,0 +1,49 @@ + +type + SharedPtr*[T] = object + val: ptr tuple[atomicCounter: int, value: T] + +proc `=destroy`*[T](p: var SharedPtr[T]) = + mixin `=destroy` + if p.val != nil: + let c = atomicDec(p.val[].atomicCounter) + if c == 0: + `=destroy`(p.val.value) + freeShared(p.val) + p.val = nil + +proc `=`*[T](dest: var SharedPtr[T], src: SharedPtr[T]) {.inline.} = + 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]) {.inline.} = + if dest.val != src.val: + if dest.val != nil: + `=destroy`(dest) + dest.val = src.val + +proc newSharedPtr*[T](val: sink T): SharedPtr[T] = + result.val = cast[type(result.val)](allocShared0(sizeof(result.val[]))) + result.val.atomicCounter = 1 + result.val.value = val + +func get*[T](p: SharedPtr[T]): var T {.inline.} = + p.val.value + +func isNil*[T](p: SharedPtr[T]): bool {.inline.} = + p.val == nil + +proc cas*[T](p, old_val: var SharedPtr[T], new_val: SharedPtr[T]): bool {.inline.} = + if old_val.val == new_val.val: + result = true + else: + result = cas(p.val.addr, old_val.val, new_val.val) + if result: + `=destroy`(old_val) + if new_val.val != nil: + discard atomicInc(new_val.val[].atomicCounter) + diff --git a/tests/destructor/trecursive.nim b/tests/destructor/trecursive.nim new file mode 100644 index 000000000..55e67f52a --- /dev/null +++ b/tests/destructor/trecursive.nim @@ -0,0 +1,34 @@ + +discard """ + output: ''' +test1 OK +''' +""" + +import smart_ptr + +type + Node[T] = object + value: T + next: SharedPtr[Node[T]] + + ForwardList[T] = object + first: SharedPtr[Node[T]] + len: Natural + +proc pushFront*[T] (list: var ForwardList[T], val: sink T) = + var newNode = newSharedPtr(Node[T](value: val)) + var result = false + while not result: + var head = list.first + newNode.get.next = head + result = list.first.cas(head, newNode) + list.len.atomicInc() + +proc test1() = + var list: ForwardList[int] + list.pushFront(1) + doAssert list.len == 1 + echo "test1 OK" + +test1() |