mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-04 22:48:38 +00:00
std: strbasics.add uses copymem when available (#25768)
`strbasics.add` uses `copymem` when available. CT conditional
scaffolding mirrors the same from system.
Follow-up to #15951
Compile-time test for `strbasics.add` undiscarded and passes, though
pending bug #15952 is still open.
This commit is contained in:
@@ -17,19 +17,30 @@ when defined(nimPreviewSlimSystem):
|
||||
|
||||
const whitespaces = {' ', '\t', '\v', '\r', '\l', '\f'}
|
||||
|
||||
const notJSnotNims = not defined(js) and not defined(nimscript)
|
||||
template whenNotVmJsNims(normalBody, restrictedBody: untyped) =
|
||||
## hack, see: #12517 #12518; Edit together with identical in `system`
|
||||
when nimvm:
|
||||
restrictedBody
|
||||
else:
|
||||
when notJSnotNims:
|
||||
normalBody
|
||||
else:
|
||||
restrictedBody
|
||||
|
||||
proc add*(x: var string, y: openArray[char]) =
|
||||
## Concatenates `x` and `y` in place. `y` must not overlap with `x` to
|
||||
## allow future `memcpy` optimizations.
|
||||
## Concatenates `x` and `y` in place. `y` must not overlap with `x`
|
||||
# Use `{.noalias.}` ?
|
||||
let n = x.len
|
||||
x.setLen n + y.len
|
||||
# pending #19727
|
||||
# setLen unnecessarily zeros memory
|
||||
var i = 0
|
||||
while i < y.len:
|
||||
x[n + i] = y[i]
|
||||
i.inc
|
||||
# xxx use `nimCopyMem(x[n].addr, y[0].addr, y.len)` after some refactoring
|
||||
if y.len == 0: return
|
||||
let oldLen = x.len
|
||||
x.setLenUninit(oldLen + y.len)
|
||||
whenNotVmJsNims():
|
||||
{.cast(noSideEffect).}:
|
||||
copyMem(beginStore(x, oldLen + y.len, oldLen), addr(y[0]), y.len)
|
||||
endStore(x)
|
||||
do:
|
||||
for i, ch in y:
|
||||
x[oldLen + i] = ch
|
||||
|
||||
func stripSlice(s: openArray[char], leading = true, trailing = true, chars: set[char] = whitespaces): Slice[int] =
|
||||
## Returns the slice range of `s` which is stripped `chars`.
|
||||
@@ -74,19 +85,14 @@ func setSlice*(s: var string, slice: Slice[int]) =
|
||||
if first > last:
|
||||
s.setLen(0)
|
||||
return
|
||||
template impl =
|
||||
for index in first .. last:
|
||||
s[index - first] = s[index]
|
||||
if first > 0:
|
||||
when nimvm: impl()
|
||||
else:
|
||||
# not JS and not Nimscript
|
||||
when not declared(moveMem):
|
||||
impl()
|
||||
else:
|
||||
let p = beginStore(s, s.len)
|
||||
moveMem(p, addr p[first], last - first + 1)
|
||||
endStore(s)
|
||||
whenNotVmJsNims():
|
||||
let p = beginStore(s, s.len)
|
||||
moveMem(p, addr p[first], last - first + 1)
|
||||
endStore(s)
|
||||
do:
|
||||
for index in first .. last:
|
||||
s[index - first] = s[index]
|
||||
s.setLen(last - first + 1)
|
||||
|
||||
func strip*(a: var string, leading = true, trailing = true, chars: set[char] = whitespaces) {.inline.} =
|
||||
|
||||
@@ -90,7 +90,8 @@ proc main() =
|
||||
var a0 = "hi"
|
||||
var b0 = "foobar"
|
||||
when nimvm:
|
||||
discard # pending bug #15952
|
||||
a0.add b0.toOpenArray(1,3)
|
||||
doAssert a0 == "hioob"
|
||||
else:
|
||||
a0.add b0.toOpenArray(1,3)
|
||||
doAssert a0 == "hioob"
|
||||
|
||||
Reference in New Issue
Block a user