123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- discard """
- output: '''10.0
- 60.0
- 90.0
- 120.0
- 10.0
- 60.0
- 90.0
- 120.0
- 8 8'''
- joinable: false
- """
- import typetraits
- type
- opt[T] = object
- data: ptr T
- var
- allocCount, deallocCount: int
- proc `=destroy`*[T](x: var opt[T]) =
- if x.data != nil:
- mixin `=destroy`
- when not supportsCopyMem(T):
- `=destroy`(x.data[])
- dealloc(x.data)
- inc deallocCount
- x.data = nil
- proc `=`*[T](a: var opt[T]; b: opt[T]) =
- if a.data == b.data: return
- if a.data != nil:
- dealloc(a.data)
- inc deallocCount
- a.data = nil
- if b.data != nil:
- a.data = cast[type(a.data)](alloc(sizeof(T)))
- inc allocCount
- when supportsCopyMem(T):
- copyMem(a.data, b.data, sizeof(T))
- else:
- a.data[] = b.data[]
- proc `=sink`*[T](a: var opt[T]; b: opt[T]) =
- if a.data != nil and a.data != b.data:
- dealloc(a.data)
- inc deallocCount
- a.data = b.data
- proc createOpt*[T](x: T): opt[T] =
- result.data = cast[type(result.data)](alloc(sizeof(T)))
- inc allocCount
- result.data[] = x
- template `[]`[T](x: opt[T]): T =
- assert x.p != nil, "attempt to read from moved/destroyed value"
- x.p[]
- template `?=`[T](it: untyped; x: opt[T]): bool =
- template it: untyped {.inject.} = x.data[]
- if x.data != nil:
- true
- else:
- false
- type
- Tree = object
- data: float
- le, ri: opt[Tree]
- proc createTree(data: float): Tree =
- result.data = data
- proc insert(t: var opt[Tree]; newVal: float) =
- #if it ?= t:
- if t.data != nil:
- if newVal < t.data[].data:
- insert(t.data[].le, newVal)
- elif t.data[].data < newVal:
- insert(t.data[].ri, newVal)
- else:
- discard "already in the tree"
- else:
- t = createOpt(Tree(data: newVal))
- proc write(t: opt[Tree]) =
- if it ?= t:
- write(it.le)
- write stdout, it.data, "\n"
- write(it.ri)
- proc use(t: opt[Tree]) = discard
- proc main =
- var t: opt[Tree]
- insert t, 60.0
- insert t, 90.0
- insert t, 10.0
- insert t, 120.0
- write t
- let copy = t
- write copy
- use t
- main()
- echo allocCount, " ", deallocCount
|