added a test case for --newruntime
This commit is contained in:
parent
63530be0b8
commit
ffe52a7f7b
1 changed files with 97 additions and 0 deletions
97
tests/destructor/tcustomstrings.nim
Normal file
97
tests/destructor/tcustomstrings.nim
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
discard """
|
||||||
|
output: '''foo bar to appendmore here
|
||||||
|
foo bar to appendmore here
|
||||||
|
foo bar to appendmore here
|
||||||
|
foo bar to appendmore here
|
||||||
|
foo bar to appendmore here
|
||||||
|
after 16 16'''
|
||||||
|
cmd: '''nim c --newruntime $file'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
mystring = object
|
||||||
|
len, cap: int
|
||||||
|
data: ptr UncheckedArray[char]
|
||||||
|
|
||||||
|
{.this: self.}
|
||||||
|
|
||||||
|
var
|
||||||
|
allocCount, deallocCount: int
|
||||||
|
|
||||||
|
proc `=destroy`*(self: var mystring) =
|
||||||
|
if data != nil:
|
||||||
|
dealloc(data)
|
||||||
|
inc deallocCount
|
||||||
|
data = nil
|
||||||
|
len = 0
|
||||||
|
cap = 0
|
||||||
|
|
||||||
|
proc `=sink`*(a: var mystring, b: mystring) =
|
||||||
|
# we hope this is optimized away for not yet alive objects:
|
||||||
|
if a.data != nil and a.data != b.data:
|
||||||
|
dealloc(a.data)
|
||||||
|
inc deallocCount
|
||||||
|
a.len = b.len
|
||||||
|
a.cap = b.cap
|
||||||
|
a.data = b.data
|
||||||
|
|
||||||
|
proc `=`*(a: var mystring; b: mystring) =
|
||||||
|
if a.data != nil and a.data != b.data:
|
||||||
|
dealloc(a.data)
|
||||||
|
inc deallocCount
|
||||||
|
a.data = nil
|
||||||
|
a.len = b.len
|
||||||
|
a.cap = b.cap
|
||||||
|
if b.data != nil:
|
||||||
|
a.data = cast[type(a.data)](alloc(a.cap + 1))
|
||||||
|
inc allocCount
|
||||||
|
copyMem(a.data, b.data, a.cap+1)
|
||||||
|
|
||||||
|
proc resize(self: var mystring) =
|
||||||
|
if cap == 0: cap = 8
|
||||||
|
else: cap = (cap * 3) shr 1
|
||||||
|
if data == nil: inc allocCount
|
||||||
|
data = cast[type(data)](realloc(data, cap + 1))
|
||||||
|
|
||||||
|
proc add*(self: var mystring; c: char) =
|
||||||
|
if self.len >= self.cap: resize(self)
|
||||||
|
self.data[self.len] = c
|
||||||
|
self.data[self.len+1] = '\0'
|
||||||
|
inc self.len
|
||||||
|
|
||||||
|
proc ensure(self: var mystring; newLen: int) =
|
||||||
|
if newLen >= cap:
|
||||||
|
cap = max((cap * 3) shr 1, newLen)
|
||||||
|
if cap > 0:
|
||||||
|
if data == nil: inc allocCount
|
||||||
|
data = cast[type(data)](realloc(data, cap + 1))
|
||||||
|
|
||||||
|
proc add*(self: var mystring; y: mystring) =
|
||||||
|
let newLen = len + y.len
|
||||||
|
ensure(self, newLen)
|
||||||
|
copyMem(addr data[len], y.data, y.data.len + 1)
|
||||||
|
len = newLen
|
||||||
|
|
||||||
|
proc create*(lit: string): mystring =
|
||||||
|
let newLen = lit.len
|
||||||
|
ensure(result, newLen)
|
||||||
|
copyMem(addr result.data[result.len], unsafeAddr lit[0], newLen + 1)
|
||||||
|
result.len = newLen
|
||||||
|
|
||||||
|
func `&`*(a, b: mystring): mystring =
|
||||||
|
result = a
|
||||||
|
result.add b
|
||||||
|
|
||||||
|
func main(n: int) =
|
||||||
|
var a: mystring
|
||||||
|
let b = create" to append"
|
||||||
|
for i in 0..<n:
|
||||||
|
if i > 4: break
|
||||||
|
a = create"foo bar"
|
||||||
|
let c = b & create"more here"
|
||||||
|
a.add c
|
||||||
|
echo cstring(a.data)
|
||||||
|
|
||||||
|
|
||||||
|
main(1000)
|
||||||
|
echo "after ", allocCount, " ", deallocCount
|
||||||
Loading…
Add table
Add a link
Reference in a new issue