Skip to content

Commit

Permalink
address comments: move to strbasics
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour committed Feb 24, 2021
1 parent 69a498b commit c1649ac
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 175 deletions.
7 changes: 2 additions & 5 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,11 @@ provided by the operating system.
dumping (on select signals) and notifying the parent process about the cause
of termination.

- Added `strip` and `setSlice` to `std/strbasics`.

- Added `std/strbasics` for high performance string operations.
Added `strip`, `setSlice`, `add(a: var string, b: openArray[char])`.

- Added to `wrapnils` an option-like API via `??.`, `isSome`, `get`.

- Added overload `ssytem.add(a: var string, b: openArray[char])`
- Added overload `sytem.add(a: var string, b: openArray[char])`
- Added overload `system.add(a: var string, b: openArray[char])`.

## Language changes

Expand Down
16 changes: 16 additions & 0 deletions lib/std/strbasics.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,25 @@
#

## This module provides some high performance string operations.
##
## Experimental API, subject to change.

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] =
## Returns the slice range of `s` which is stripped `chars`.
runnableExamples:
Expand Down
27 changes: 8 additions & 19 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1069,27 +1069,16 @@ proc add*(x: var string, y: char) {.magic: "AppendStrCh", noSideEffect.}
## tmp.add('a')
## tmp.add('b')
## 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.
##
## .. code-block:: Nim
## var tmp = ""
## tmp.add("ab")
## tmp.add("cd")
## assert(tmp == "abcd")

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.
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
## See also `strbasics.add`.
runnableExamples:
var tmp = ""
tmp.add("ab")
tmp.add("cd")
assert tmp == "abcd"

type
Endianness* = enum ## Type describing the endianness of a processor.
Expand Down
10 changes: 5 additions & 5 deletions tests/concepts/t3330.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ proc add(x: var string; y: cstring)
first type mismatch at position: 1
required type for x: var string
but expression 'k' is of type: Alias
proc add(x: var string; y: openArray[char])
first type mismatch at position: 1
required type for x: var string
but expression 'k' is of type: Alias
proc add(x: var string; y: string)
first type mismatch at position: 1
required type for x: var string
Expand Down Expand Up @@ -47,9 +43,13 @@ expression: test(bar)'''



## line 50






## line 60
type
Foo[T] = concept k
add(k, string, T)
Expand Down
253 changes: 133 additions & 120 deletions tests/stdlib/tstrbasics.nim
Original file line number Diff line number Diff line change
@@ -1,126 +1,139 @@
discard """
targets: "c cpp js"
matrix: "--gc:refc; --gc:arc"
"""

import std/[strbasics, sugar]


proc teststrip() =
var a = " vhellov "
strip(a)
doAssert a == "vhellov"

a = " vhellov "
a.strip(leading = false)
doAssert a == " vhellov"

a = " vhellov "
a.strip(trailing = false)
doAssert a == "vhellov "

a.strip()
a.strip(chars = {'v'})
doAssert a == "hello"

a = " vhellov "
a.strip()
a.strip(leading = false, chars = {'v'})
doAssert a == "vhello"

var c = "blaXbla"
c.strip(chars = {'b', 'a'})
doAssert c == "laXbl"
c = "blaXbla"
c.strip(chars = {'b', 'a', 'l'})
doAssert c == "X"

block:
var a = "xxxxxx"
a.strip(chars={'x'})
doAssert a.len == 0

block:
var a = "x"
a.strip(chars={'x'})
doAssert a.len == 0

block:
var a = "x"
a.strip(chars={'1'})
doAssert a.len == 1

block:
var a = ""
a.strip(chars={'x'})
doAssert a.len == 0

block:
var a = "xxx xxx"
a.strip(chars={'x'})
doAssert a == " "

block:
var a = "xxx wind"
a.strip(chars={'x'})
doAssert a == " wind"

block:
var a = "xxx iii"
a.strip(chars={'i'})
doAssert a == "xxx "

block:
var a = "xxx iii"
doAssert a.dup(strip(chars = {'i'})) == "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:
var a = "x i"
doAssert a.dup(strip(chars = {'i'})) == "x "
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'})) == " "
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0

block:
var a = ""
doAssert a.dup(strip(chars = {'i'})).len == 0
doAssert a.dup(strip(chars = {' '})).len == 0
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', ' '})).len == 0

block:
var a = " "
doAssert a.dup(strip(chars = {'i'})) == " "
doAssert a.dup(strip(chars = {' '})).len == 0
doAssert a.dup(strip(chars = {'x'})) == " "
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0


block:
var a = "Hello, Nim!"
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


doAssertRaises(AssertionDefect):
discard a.dup(setSlice(-1 .. 1))

doAssertRaises(AssertionDefect):
discard a.dup(setSlice(1 .. 11))

static: teststrip()
teststrip()
proc main() =
block: # strip
when not defined(gcArc): # pending bug #17173
var a = " vhellov "
strip(a)
doAssert a == "vhellov"

a = " vhellov "
a.strip(leading = false)
doAssert a == " vhellov"

a = " vhellov "
a.strip(trailing = false)
doAssert a == "vhellov "

a.strip()
a.strip(chars = {'v'})
doAssert a == "hello"

a = " vhellov "
a.strip()
a.strip(leading = false, chars = {'v'})
doAssert a == "vhello"

var c = "blaXbla"
c.strip(chars = {'b', 'a'})
doAssert c == "laXbl"
c = "blaXbla"
c.strip(chars = {'b', 'a', 'l'})
doAssert c == "X"

block:
var a = "xxxxxx"
a.strip(chars={'x'})
doAssert a.len == 0

block:
var a = "x"
a.strip(chars={'x'})
doAssert a.len == 0

block:
var a = "x"
a.strip(chars={'1'})
doAssert a.len == 1

block:
var a = ""
a.strip(chars={'x'})
doAssert a.len == 0

block:
var a = "xxx xxx"
a.strip(chars={'x'})
doAssert a == " "

block:
var a = "xxx wind"
a.strip(chars={'x'})
doAssert a == " wind"

block:
var a = "xxx iii"
a.strip(chars={'i'})
doAssert a == "xxx "

block:
var a = "xxx iii"
doAssert a.dup(strip(chars = {'i'})) == "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:
var a = "x i"
doAssert a.dup(strip(chars = {'i'})) == "x "
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'})) == " "
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0

block:
var a = ""
doAssert a.dup(strip(chars = {'i'})).len == 0
doAssert a.dup(strip(chars = {' '})).len == 0
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', ' '})).len == 0

block:
var a = " "
doAssert a.dup(strip(chars = {'i'})) == " "
doAssert a.dup(strip(chars = {' '})).len == 0
doAssert a.dup(strip(chars = {'x'})) == " "
doAssert a.dup(strip(chars = {'x', ' '})).len == 0
doAssert a.dup(strip(chars = {'x', 'i'})) == " "
doAssert a.dup(strip(chars = {'x', 'i', ' '})).len == 0

block: # setSlice
var a = "Hello, Nim!"
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

doAssertRaises(AssertionDefect):
discard a.dup(setSlice(-1 .. 1))

doAssertRaises(AssertionDefect):
discard a.dup(setSlice(1 .. 11))

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'

static: main()
main()
Loading

0 comments on commit c1649ac

Please sign in to comment.