-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add strbasics.strip #16280
add strbasics.strip #16280
Changes from all commits
c39b1ee
0739383
bec8c5e
d435db3
1ef34d3
8cf7c65
934454e
bddc4bb
5efcdc6
00c0447
14c418a
3598878
0b9fed9
6438df9
376bf9a
babe83a
a244112
3dbc80d
5e99baa
1c4f6e6
5062d12
10d9ba3
c06ae25
b8d9e0d
9925a62
69b8683
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# | ||
# | ||
# The Nim Compiler | ||
# (c) Copyright 2021 Nim Contributors | ||
# | ||
# See the file "copying.txt", included in this | ||
# distribution, for details about the copyright. | ||
# | ||
|
||
## This module provides some high performance string operations. | ||
|
||
const whitespaces = {' ', '\t', '\v', '\r', '\l', '\f'} | ||
|
||
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: | ||
assert stripSlice(" abc ") == 1 .. 3 | ||
var | ||
first = 0 | ||
last = high(s) | ||
if leading: | ||
while first <= last and s[first] in chars: inc(first) | ||
if trailing: | ||
while last >= first and s[last] in chars: dec(last) | ||
result = first .. last | ||
|
||
func setSlice*(s: var string, slice: Slice[int]) = | ||
## Inplace version of `substr`. | ||
runnableExamples: | ||
import std/sugar | ||
|
||
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)) | ||
|
||
|
||
let first = slice.a | ||
let last = slice.b | ||
|
||
assert first >= 0 | ||
assert last <= s.high | ||
|
||
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() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see whether we can use (refs #16280 (comment)) |
||
else: | ||
moveMem(addr s[0], addr s[first], last - first + 1) | ||
s.setLen(last - first + 1) | ||
|
||
func strip*(a: var string, leading = true, trailing = true, chars: set[char] = whitespaces) {.inline.} = | ||
## Inplace version of `strip`. Strips leading or | ||
## trailing `chars` (default: whitespace characters). | ||
## | ||
## If `leading` is true (default), leading `chars` are stripped. | ||
## If `trailing` is true (default), trailing `chars` are stripped. | ||
## If both are false, the string is unchanged. | ||
runnableExamples: | ||
var a = " vhellov " | ||
strip(a) | ||
assert a == "vhellov" | ||
|
||
a = " vhellov " | ||
a.strip(leading = false) | ||
assert a == " vhellov" | ||
|
||
a = " vhellov " | ||
a.strip(trailing = false) | ||
assert a == "vhellov " | ||
|
||
var c = "blaXbla" | ||
c.strip(chars = {'b', 'a'}) | ||
assert c == "laXbl" | ||
c = "blaXbla" | ||
c.strip(chars = {'b', 'a', 'l'}) | ||
assert c == "X" | ||
|
||
setSlice(a, stripSlice(a, leading, trailing, chars)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
discard """ | ||
targets: "c cpp js" | ||
""" | ||
|
||
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() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
teststrip() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std/strbasics
containingstrip
andsetSlice
.