mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-08 14:03:23 +00:00
102 lines
2.7 KiB
Nim
102 lines
2.7 KiB
Nim
discard """
|
|
output: '''true
|
|
5.0'''
|
|
"""
|
|
|
|
#bug #592
|
|
|
|
type
|
|
ElementKind = enum inner, leaf
|
|
TElement[TKey, TData] = object
|
|
case kind: ElementKind
|
|
of inner:
|
|
key: TKey
|
|
left, right: ref TElement[Tkey, TData]
|
|
of leaf:
|
|
data: TData
|
|
PElement[TKey, TData] = ref TElement[TKey, TData]
|
|
|
|
proc newElement[Tkey, TData](other: PElement[TKey, TData]): PElement[Tkey, TData] =
|
|
case other.kind:
|
|
of inner:
|
|
PElement[TKey, TData](kind: ElementKind.inner, key: other.key, left: other.left, right: other.right)
|
|
of leaf:
|
|
PElement[TKey, TData](kind: ElementKind.leaf, data: other.data)
|
|
|
|
proc newElement[TKey, TData](key: TKey, left: PElement[TKey, TData] = nil, right: PElement[TKey, TData] = nil) : PElement[TKey, TData] =
|
|
PElement[TKey, TData](kind: ElementKind.inner, key: key, left: left, right: right)
|
|
|
|
proc newElement[Tkey, TData](key: Tkey, data: TData) : PElement[Tkey, TData] =
|
|
PElement[TKey, TData](kind: ElementKind.leaf, data: data)
|
|
|
|
proc find*[TKey, TData](root: PElement[TKey, TData], key: TKey): TData {.raises: [KeyError].} =
|
|
if root.left == nil:
|
|
raise newException(KeyError, "key does not exist: " & key)
|
|
|
|
var tmp_element = addr(root)
|
|
|
|
while tmp_element.kind == inner and tmp_element.right != nil:
|
|
tmp_element = if tmp_element.key > key:
|
|
addr(tmp_element.left)
|
|
else:
|
|
addr(tmp_element.right)
|
|
|
|
if tmp_element.key == key:
|
|
return tmp_element.left.data
|
|
else:
|
|
raise newException(KeyError, "key does not exist: " & key)
|
|
|
|
proc add*[TKey, TData](root: var PElement[TKey, TData], key: TKey, data: TData) : bool =
|
|
if root.left == nil:
|
|
root.key = key
|
|
root.left = newElement[TKey, TData](key, data)
|
|
return true
|
|
|
|
var tmp_element = addr(root)
|
|
|
|
while tmp_element.kind == ElementKind.inner and tmp_element.right != nil:
|
|
tmp_element = if tmp_element.key > key:
|
|
addr(tmp_element.left)
|
|
else:
|
|
addr(tmp_element.right)
|
|
|
|
if tmp_element.key == key:
|
|
return false
|
|
|
|
var old_element = newElement[TKey, TData](tmp_element[])
|
|
var new_element = newElement[TKey, TData](key, data)
|
|
|
|
tmp_element[] = if tmp_element.key < key:
|
|
newElement(key, old_element, new_element)
|
|
else:
|
|
newElement(tmp_element.key, new_element, old_element)
|
|
|
|
return true
|
|
|
|
var tree = PElement[int, int](kind: ElementKind.inner, key: 0, left: nil, right: nil)
|
|
let result = add(tree, 1, 1)
|
|
echo(result)
|
|
|
|
# bug #3748
|
|
type
|
|
Foo = object
|
|
bar: int
|
|
|
|
proc bar(cur: Foo, val: int, s:seq[string]) =
|
|
discard cur.bar
|
|
|
|
proc does_fail(): Foo =
|
|
let a = @["a"]
|
|
result.bar(5, a)
|
|
|
|
doAssert does_fail().bar == 0
|
|
|
|
# bug #20645
|
|
|
|
type Zzz[Gen] = object
|
|
|
|
proc testZ(z: Zzz) =
|
|
echo z.Gen(5)
|
|
|
|
testZ(Zzz[float]())
|