1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- 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 20 20'''
- joinable: false
- """
- type
- mystring = object
- len, cap: int
- data: ptr UncheckedArray[char]
- var
- allocCount, deallocCount: int
- proc `=destroy`*(s: var mystring) =
- if s.data != nil:
- dealloc(s.data)
- inc deallocCount
- s.data = nil
- s.len = 0
- s.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 self.cap == 0: self.cap = 8
- else: self.cap = (self.cap * 3) shr 1
- if self.data == nil: inc allocCount
- self.data = cast[type(self.data)](realloc(self.data, self.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 >= self.cap:
- self.cap = max((self.cap * 3) shr 1, newLen)
- if self.cap > 0:
- if self.data == nil: inc allocCount
- self.data = cast[type(self.data)](realloc(self.data, self.cap + 1))
- proc add*(self: var mystring; y: mystring) =
- let newLen = self.len + y.len
- ensure(self, newLen)
- copyMem(addr self.data[self.len], y.data, y.data.len + 1)
- self.len = newLen
- proc create*(lit: string): mystring =
- let newLen = lit.len
- ensure(result, newLen)
- copyMem(addr result.data[result.len], addr lit[0], newLen + 1)
- result.len = newLen
- proc `&`*(a, b: mystring): mystring =
- result = a
- result.add b
- proc 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)
- var x: array[4, mystring]
- for i in 0..high(x): x[i] = create"added to array"
- main(1000)
- echo "after ", allocCount, " ", deallocCount
|