mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-01 02:42:05 +00:00
added a test case for --newruntime
This commit is contained in:
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
|
||||
Reference in New Issue
Block a user