mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 10:22:15 +00:00
* mark user defined destructors with sfOverriden to simplify the logic * refactoring in preparation to merge liftings and generic instantiations for destructors * ast: introduce nkHiddenTryStmt for destructor generation in order to be able to optimize better the code later on * renamed 'patterns' switch to 'trmacros' as it was totally misleading before * destructors: introduce tfCheckedForDestructor flag in preparation of strict =destroy checking * test for invalid/too late destructor introductions * liftdestructors: make code robust for nimsuggest * --newruntime works for hello world again * newruntime: code generation for closures
109 lines
2.0 KiB
Nim
109 lines
2.0 KiB
Nim
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
|