1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

builtin: optimise the common case of s.contains("x") add s.contains_byte(x) (#17702)

This commit is contained in:
Delyan Angelov 2023-03-19 00:10:13 +02:00 committed by GitHub
parent 14148f3e52
commit 3793bf1c99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 10 deletions

View File

@ -1287,12 +1287,12 @@ pub fn (s string) index_after(p string, start int) int {
return -1 return -1
} }
// index_byte returns the index of byte `c` if found in the string. // index_u8 returns the index of byte `c` if found in the string.
// index_byte returns -1 if the byte can not be found. // index_u8 returns -1 if the byte can not be found.
[direct_array_access] [direct_array_access]
pub fn (s string) index_u8(c u8) int { pub fn (s string) index_u8(c u8) int {
for i in 0 .. s.len { for i, b in s {
if unsafe { s.str[i] } == c { if b == c {
return i return i
} }
} }
@ -1348,22 +1348,33 @@ pub fn (s string) count(substr string) int {
return 0 // TODO can never get here - v doesn't know that return 0 // TODO can never get here - v doesn't know that
} }
// contains_u8 returns `true` if the string contains the byte value `x`.
// See also: [`string.index_u8`](#string.index_u8) , to get the index of the byte as well.
pub fn (s string) contains_u8(x u8) bool {
for c in s {
if x == c {
return true
}
}
return false
}
// contains returns `true` if the string contains `substr`. // contains returns `true` if the string contains `substr`.
// See also: [`string.index`](#string.index) // See also: [`string.index`](#string.index)
pub fn (s string) contains(substr string) bool { pub fn (s string) contains(substr string) bool {
if substr.len == 0 { if substr.len == 0 {
return true return true
} }
if s.index_(substr) == -1 { if substr.len == 1 {
return false return s.contains_u8(unsafe { substr.str[0] })
} }
return true return s.index_(substr) != -1
} }
// contains_any returns `true` if the string contains any chars in `chars`. // contains_any returns `true` if the string contains any chars in `chars`.
pub fn (s string) contains_any(chars string) bool { pub fn (s string) contains_any(chars string) bool {
for c in chars { for c in chars {
if s.contains(c.ascii_str()) { if s.contains_u8(c) {
return true return true
} }
} }

View File

@ -1,5 +1,3 @@
import strings
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
@ -1213,3 +1211,35 @@ fn test_indent_width() {
assert '\t\tabc'.indent_width() == 2 assert '\t\tabc'.indent_width() == 2
assert '\t\t abc'.indent_width() == 3 assert '\t\t abc'.indent_width() == 3
} }
fn test_index_u8() {
assert 'abcabca'.index_u8(`a`) == 0
assert 'abcabca'.index_u8(`b`) == 1
assert 'abcabca'.index_u8(`c`) == 2
//
assert 'abc'.index_u8(`d`) == -1
assert 'abc'.index_u8(`A`) == -1
assert 'abc'.index_u8(`B`) == -1
assert 'abc'.index_u8(`C`) == -1
//
}
fn test_last_index_u8() {
assert 'abcabca'.last_index_u8(`a`) == 6
assert 'abcabca'.last_index_u8(`c`) == 5
assert 'abcabca'.last_index_u8(`b`) == 4
assert 'Zabcabca'.last_index_u8(`Z`) == 0
//
assert 'abc'.index_u8(`d`) == -1
assert 'abc'.index_u8(`A`) == -1
assert 'abc'.index_u8(`B`) == -1
assert 'abc'.index_u8(`C`) == -1
}
fn test_contains_byte() {
assert 'abc abca'.contains_u8(`a`)
assert 'abc abca'.contains_u8(`b`)
assert 'abc abca'.contains_u8(`c`)
assert 'abc abca'.contains_u8(` `)
assert !'abc abca'.contains_u8(`A`)
}