add overload add(a: var string, b: openArray[char]) (#15951)
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
parent
dd6b0f81ef
commit
0cb02fbbee
5 changed files with 152 additions and 122 deletions
|
|
@ -173,9 +173,10 @@ provided by the operating system.
|
||||||
dumping (on select signals) and notifying the parent process about the cause
|
dumping (on select signals) and notifying the parent process about the cause
|
||||||
of termination.
|
of termination.
|
||||||
|
|
||||||
- `hashes.hash` now supports `object`, but can be overloaded.
|
- Added `std/strbasics` for high performance string operations.
|
||||||
|
Added `strip`, `setSlice`, `add(a: var string, b: openArray[char])`.
|
||||||
|
|
||||||
- Added `strip` and `setSlice` to `std/strbasics`.
|
- `hashes.hash` now supports `object`, but can be overloaded.
|
||||||
|
|
||||||
- Added to `wrapnils` an option-like API via `??.`, `isSome`, `get`.
|
- Added to `wrapnils` an option-like API via `??.`, `isSome`, `get`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,25 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
## This module provides some high performance string operations.
|
## This module provides some high performance string operations.
|
||||||
|
##
|
||||||
|
## Experimental API, subject to change.
|
||||||
|
|
||||||
const whitespaces = {' ', '\t', '\v', '\r', '\l', '\f'}
|
const whitespaces = {' ', '\t', '\v', '\r', '\l', '\f'}
|
||||||
|
|
||||||
|
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.
|
||||||
|
# Use `{.noalias.}` ?
|
||||||
|
let n = x.len
|
||||||
|
x.setLen n + y.len
|
||||||
|
# pending https://github.com/nim-lang/Nim/issues/14655#issuecomment-643671397
|
||||||
|
# use x.setLen(n + y.len, isInit = false)
|
||||||
|
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
|
||||||
|
|
||||||
func stripSlice(s: openArray[char], leading = true, trailing = true, chars: set[char] = whitespaces): Slice[int] =
|
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`.
|
## Returns the slice range of `s` which is stripped `chars`.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
|
|
|
||||||
|
|
@ -1069,15 +1069,16 @@ proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.}
|
||||||
## tmp.add('a')
|
## tmp.add('a')
|
||||||
## tmp.add('b')
|
## tmp.add('b')
|
||||||
## assert(tmp == "ab")
|
## assert(tmp == "ab")
|
||||||
proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.}
|
|
||||||
|
proc add*(x: var string, y: string) {.magic: "AppendStrStr", noSideEffect.} =
|
||||||
## Concatenates `x` and `y` in place.
|
## Concatenates `x` and `y` in place.
|
||||||
##
|
##
|
||||||
## .. code-block:: Nim
|
## See also `strbasics.add`.
|
||||||
## var tmp = ""
|
runnableExamples:
|
||||||
## tmp.add("ab")
|
var tmp = ""
|
||||||
## tmp.add("cd")
|
tmp.add("ab")
|
||||||
## assert(tmp == "abcd")
|
tmp.add("cd")
|
||||||
|
assert tmp == "abcd"
|
||||||
|
|
||||||
type
|
type
|
||||||
Endianness* = enum ## Type describing the endianness of a processor.
|
Endianness* = enum ## Type describing the endianness of a processor.
|
||||||
|
|
|
||||||
|
|
@ -1,126 +1,139 @@
|
||||||
discard """
|
discard """
|
||||||
targets: "c cpp js"
|
targets: "c cpp js"
|
||||||
|
matrix: "--gc:refc; --gc:arc"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import std/[strbasics, sugar]
|
import std/[strbasics, sugar]
|
||||||
|
|
||||||
|
proc main() =
|
||||||
|
when not defined(gcArc): # pending bug #17173
|
||||||
|
block: # strip
|
||||||
|
var a = " vhellov "
|
||||||
|
strip(a)
|
||||||
|
doAssert a == "vhellov"
|
||||||
|
|
||||||
proc teststrip() =
|
a = " vhellov "
|
||||||
var a = " vhellov "
|
a.strip(leading = false)
|
||||||
strip(a)
|
doAssert a == " vhellov"
|
||||||
doAssert a == "vhellov"
|
|
||||||
|
|
||||||
a = " vhellov "
|
a = " vhellov "
|
||||||
a.strip(leading = false)
|
a.strip(trailing = false)
|
||||||
doAssert a == " vhellov"
|
doAssert a == "vhellov "
|
||||||
|
|
||||||
a = " vhellov "
|
a.strip()
|
||||||
a.strip(trailing = false)
|
a.strip(chars = {'v'})
|
||||||
doAssert a == "vhellov "
|
doAssert a == "hello"
|
||||||
|
|
||||||
a.strip()
|
a = " vhellov "
|
||||||
a.strip(chars = {'v'})
|
a.strip()
|
||||||
doAssert a == "hello"
|
a.strip(leading = false, chars = {'v'})
|
||||||
|
doAssert a == "vhello"
|
||||||
|
|
||||||
a = " vhellov "
|
var c = "blaXbla"
|
||||||
a.strip()
|
c.strip(chars = {'b', 'a'})
|
||||||
a.strip(leading = false, chars = {'v'})
|
doAssert c == "laXbl"
|
||||||
doAssert a == "vhello"
|
c = "blaXbla"
|
||||||
|
c.strip(chars = {'b', 'a', 'l'})
|
||||||
|
doAssert c == "X"
|
||||||
|
|
||||||
var c = "blaXbla"
|
block:
|
||||||
c.strip(chars = {'b', 'a'})
|
var a = "xxxxxx"
|
||||||
doAssert c == "laXbl"
|
a.strip(chars={'x'})
|
||||||
c = "blaXbla"
|
doAssert a.len == 0
|
||||||
c.strip(chars = {'b', 'a', 'l'})
|
|
||||||
doAssert c == "X"
|
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "xxxxxx"
|
var a = "x"
|
||||||
a.strip(chars={'x'})
|
a.strip(chars={'x'})
|
||||||
doAssert a.len == 0
|
doAssert a.len == 0
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "x"
|
var a = "x"
|
||||||
a.strip(chars={'x'})
|
a.strip(chars={'1'})
|
||||||
doAssert a.len == 0
|
doAssert a.len == 1
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "x"
|
var a = ""
|
||||||
a.strip(chars={'1'})
|
a.strip(chars={'x'})
|
||||||
doAssert a.len == 1
|
doAssert a.len == 0
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = ""
|
var a = "xxx xxx"
|
||||||
a.strip(chars={'x'})
|
a.strip(chars={'x'})
|
||||||
doAssert a.len == 0
|
doAssert a == " "
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "xxx xxx"
|
var a = "xxx wind"
|
||||||
a.strip(chars={'x'})
|
a.strip(chars={'x'})
|
||||||
doAssert a == " "
|
doAssert a == " wind"
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "xxx wind"
|
var a = "xxx iii"
|
||||||
a.strip(chars={'x'})
|
a.strip(chars={'i'})
|
||||||
doAssert a == " wind"
|
doAssert a == "xxx "
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "xxx iii"
|
var a = "xxx iii"
|
||||||
a.strip(chars={'i'})
|
doAssert a.dup(strip(chars = {'i'})) == "xxx "
|
||||||
doAssert a == "xxx "
|
doAssert a.dup(strip(chars = {' '})) == "xxx iii"
|
||||||
|
doAssert a.dup(strip(chars = {'x'})) == " iii"
|
||||||
|
doAssert a.dup(strip(chars = {'x', ' '})) == "iii"
|
||||||
|
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
||||||
|
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "xxx iii"
|
var a = "x i"
|
||||||
doAssert a.dup(strip(chars = {'i'})) == "xxx "
|
doAssert a.dup(strip(chars = {'i'})) == "x "
|
||||||
doAssert a.dup(strip(chars = {' '})) == "xxx iii"
|
doAssert a.dup(strip(chars = {' '})) == "x i"
|
||||||
doAssert a.dup(strip(chars = {'x'})) == " iii"
|
doAssert a.dup(strip(chars = {'x'})) == " i"
|
||||||
doAssert a.dup(strip(chars = {'x', ' '})) == "iii"
|
doAssert a.dup(strip(chars = {'x', ' '})) == "i"
|
||||||
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
||||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = "x i"
|
var a = ""
|
||||||
doAssert a.dup(strip(chars = {'i'})) == "x "
|
doAssert a.dup(strip(chars = {'i'})).len == 0
|
||||||
doAssert a.dup(strip(chars = {' '})) == "x i"
|
doAssert a.dup(strip(chars = {' '})).len == 0
|
||||||
doAssert a.dup(strip(chars = {'x'})) == " i"
|
doAssert a.dup(strip(chars = {'x'})).len == 0
|
||||||
doAssert a.dup(strip(chars = {'x', ' '})) == "i"
|
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
|
||||||
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
doAssert a.dup(strip(chars = {'x', 'i'})).len == 0
|
||||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var a = ""
|
var a = " "
|
||||||
doAssert a.dup(strip(chars = {'i'})).len == 0
|
doAssert a.dup(strip(chars = {'i'})) == " "
|
||||||
doAssert a.dup(strip(chars = {' '})).len == 0
|
doAssert a.dup(strip(chars = {' '})).len == 0
|
||||||
doAssert a.dup(strip(chars = {'x'})).len == 0
|
doAssert a.dup(strip(chars = {'x'})) == " "
|
||||||
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
|
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
|
||||||
doAssert a.dup(strip(chars = {'x', 'i'})).len == 0
|
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
||||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
||||||
|
|
||||||
block:
|
block: # setSlice
|
||||||
var a = " "
|
var a = "Hello, Nim!"
|
||||||
doAssert a.dup(strip(chars = {'i'})) == " "
|
doassert a.dup(setSlice(7 .. 9)) == "Nim"
|
||||||
doAssert a.dup(strip(chars = {' '})).len == 0
|
doAssert a.dup(setSlice(0 .. 0)) == "H"
|
||||||
doAssert a.dup(strip(chars = {'x'})) == " "
|
doAssert a.dup(setSlice(0 .. 1)) == "He"
|
||||||
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
|
doAssert a.dup(setSlice(0 .. 10)) == a
|
||||||
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
|
doAssert a.dup(setSlice(1 .. 0)).len == 0
|
||||||
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0
|
doAssert a.dup(setSlice(20 .. -1)).len == 0
|
||||||
|
|
||||||
|
doAssertRaises(AssertionDefect):
|
||||||
|
discard a.dup(setSlice(-1 .. 1))
|
||||||
|
|
||||||
block:
|
doAssertRaises(AssertionDefect):
|
||||||
var a = "Hello, Nim!"
|
discard a.dup(setSlice(1 .. 11))
|
||||||
doassert a.dup(setSlice(7 .. 9)) == "Nim"
|
|
||||||
doAssert a.dup(setSlice(0 .. 0)) == "H"
|
|
||||||
doAssert a.dup(setSlice(0 .. 1)) == "He"
|
|
||||||
doAssert a.dup(setSlice(0 .. 10)) == a
|
|
||||||
doAssert a.dup(setSlice(1 .. 0)).len == 0
|
|
||||||
doAssert a.dup(setSlice(20 .. -1)).len == 0
|
|
||||||
|
|
||||||
|
block: # add
|
||||||
|
var a0 = "hi"
|
||||||
|
var b0 = "foobar"
|
||||||
|
when nimvm:
|
||||||
|
discard # pending bug #15952
|
||||||
|
else:
|
||||||
|
a0.add b0.toOpenArray(1,3)
|
||||||
|
doAssert a0 == "hioob"
|
||||||
|
proc fn(c: openArray[char]): string =
|
||||||
|
result.add c
|
||||||
|
doAssert fn("def") == "def"
|
||||||
|
doAssert fn(['d','\0', 'f'])[2] == 'f'
|
||||||
|
|
||||||
doAssertRaises(AssertionDefect):
|
static: main()
|
||||||
discard a.dup(setSlice(-1 .. 1))
|
main()
|
||||||
|
|
||||||
doAssertRaises(AssertionDefect):
|
|
||||||
discard a.dup(setSlice(1 .. 11))
|
|
||||||
|
|
||||||
static: teststrip()
|
|
||||||
teststrip()
|
|
||||||
|
|
|
||||||
|
|
@ -12,16 +12,16 @@ proc set_all[T](s: var openArray[T]; val: T) =
|
||||||
for i in 0..<s.len:
|
for i in 0..<s.len:
|
||||||
s[i] = val
|
s[i] = val
|
||||||
|
|
||||||
proc test() =
|
proc main() =
|
||||||
var a0 = "hello_world"
|
var a0 = "hello_world"
|
||||||
var a1 = [1,2,3,4,5,6,7,8,9]
|
var a1 = [1,2,3,4,5,6,7,8,9]
|
||||||
var a2 = @[1,2,3,4,5,6,7,8,9]
|
var a2 = @[1,2,3,4,5,6,7,8,9]
|
||||||
a0.set_all('i')
|
a0.set_all('i')
|
||||||
a1.set_all(4)
|
a1.set_all(4)
|
||||||
a2.set_all(4)
|
a2.set_all(4)
|
||||||
doAssert a0 == "iiiiiiiiiii"
|
doAssert a0 == "iiiiiiiiiii"
|
||||||
doAssert a1 == [4,4,4,4,4,4,4,4,4]
|
doAssert a1 == [4,4,4,4,4,4,4,4,4]
|
||||||
doAssert a2 == @[4,4,4,4,4,4,4,4,4]
|
doAssert a2 == @[4,4,4,4,4,4,4,4,4]
|
||||||
|
|
||||||
const constval0 = "hello".map(proc(x: char): char = x)
|
const constval0 = "hello".map(proc(x: char): char = x)
|
||||||
const constval1 = [1,2,3,4].map(proc(x: int): int = x)
|
const constval1 = [1,2,3,4].map(proc(x: int): int = x)
|
||||||
|
|
@ -29,6 +29,5 @@ const constval1 = [1,2,3,4].map(proc(x: int): int = x)
|
||||||
doAssert("hello".map(proc(x: char): char = x) == constval0)
|
doAssert("hello".map(proc(x: char): char = x) == constval0)
|
||||||
doAssert([1,2,3,4].map(proc(x: int): int = x) == constval1)
|
doAssert([1,2,3,4].map(proc(x: int): int = x) == constval1)
|
||||||
|
|
||||||
test()
|
static: main()
|
||||||
static:
|
main()
|
||||||
test()
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue