Destructors: move into nkTupleConstr and move on tuple unpacking (#9776)

This commit is contained in:
cooldome
2018-11-22 17:33:19 +00:00
committed by Andreas Rumpf
parent f8fa94cb20
commit 962b2e4b39
3 changed files with 96 additions and 9 deletions

View File

@@ -1,21 +1,26 @@
discard """
exitcode: 0
output: '''assingment
assingment
assingment
assingment
'''
output: ""
"""
type
Foo* = object
boo: int
var sink_counter = 0
var assign_counter = 0
proc `=sink`(dest: var Foo, src: Foo) =
sink_counter.inc
proc `=`(dest: var Foo, src: Foo) =
debugEcho "assingment"
assign_counter.inc
proc test(): auto =
var a,b : Foo
return (a, b)
return (a, b, Foo(boo: 5))
var (a, b) = test()
var (a, b, _) = test()
doAssert: assign_counter == 0
doAssert: sink_counter == 9

View File

@@ -60,3 +60,62 @@ for x in getPony():
# XXX this needs to be enabled once top level statements
# produce destructor calls again.
#echo "Pony is dying!"
#------------------------------------------------------------
#-- Move into tuple constructor and move on tuple unpacking
#------------------------------------------------------------
type
MySeqNonCopyable* = object
len: int
data: ptr UncheckedArray[float]
proc `=destroy`*(m: var MySeqNonCopyable) {.inline.} =
if m.data != nil:
deallocShared(m.data)
m.data = nil
proc `=`*(m: var MySeqNonCopyable, m2: MySeqNonCopyable) {.error.}
proc `=sink`*(m: var MySeqNonCopyable, m2: MySeqNonCopyable) {.inline.} =
if m.data != m2.data:
if m.data != nil:
`=destroy`(m)
m.len = m2.len
m.data = m2.data
proc len*(m: MySeqNonCopyable): int {.inline.} = m.len
proc `[]`*(m: MySeqNonCopyable; i: int): float {.inline.} =
m.data[i.int]
proc `[]=`*(m: var MySeqNonCopyable; i, val: float) {.inline.} =
m.data[i.int] = val
proc setTo(s: var MySeqNonCopyable, val: float) =
for i in 0..<s.len.int:
s.data[i] = val
proc newMySeq*(size: int, initial_value = 0.0): MySeqNonCopyable =#
result.len = size
if size > 0:
result.data = cast[ptr UncheckedArray[float]](createShared(float, size))
result.setTo(initial_value)
proc myfunc(x, y: int): (MySeqNonCopyable, MySeqNonCopyable) =
result = (newMySeq(x, 1.0), newMySeq(y, 5.0))
proc myfunc2(x, y: int): tuple[a: MySeqNonCopyable, b:int, c:MySeqNonCopyable] =
(a: newMySeq(x, 1.0), b:0, c:newMySeq(y, 5.0))
let (seq1, seq2) = myfunc(2, 3)
doAssert seq1.len == 2
doAssert seq1[0] == 1.0
doAssert seq2.len == 3
doAssert seq2[0] == 5.0
var (seq3, i, _) = myfunc2(2, 3)
doAssert seq3.len == 2
doAssert seq3[0] == 1.0