mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Improve strings.index_any and strings.last_index_any
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
//+private
|
||||||
|
package strings
|
||||||
|
|
||||||
|
import "core:unicode/utf8"
|
||||||
|
|
||||||
|
Ascii_Set :: distinct [8]u32;
|
||||||
|
|
||||||
|
ascii_set_make :: proc(chars: string) -> (as: Ascii_Set, ok: bool) #no_bounds_check {
|
||||||
|
for i in 0..<len(chars) {
|
||||||
|
c := chars[i];
|
||||||
|
if c >= utf8.RUNE_SELF {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
as[c>>5] |= 1 << uint(c&31);
|
||||||
|
}
|
||||||
|
ok = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ascii_set_contains :: proc(as: Ascii_Set, c: byte) -> bool #no_bounds_check {
|
||||||
|
return as[c>>5] & (1<<(c&31)) != 0;
|
||||||
|
}
|
||||||
+61
-12
@@ -479,17 +479,34 @@ last_index :: proc(s, substr: string) -> int {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
index_any :: proc(s, chars: string) -> int {
|
index_any :: proc(s, chars: string) -> int {
|
||||||
if chars == "" {
|
if chars == "" {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bill): Optimize
|
if len(chars) == 1 {
|
||||||
for r, i in s {
|
r := rune(chars[0]);
|
||||||
for c in chars {
|
if r >= utf8.RUNE_SELF {
|
||||||
if r == c {
|
r = utf8.RUNE_ERROR;
|
||||||
return i;
|
}
|
||||||
|
return index_rune(s, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s) > 8 {
|
||||||
|
if as, ok := ascii_set_make(chars); ok {
|
||||||
|
for i in 0..<len(s) {
|
||||||
|
if ascii_set_contains(as, s[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for c, i in chars {
|
||||||
|
if index_rune(chars, c) >= 0 {
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -499,15 +516,47 @@ last_index_any :: proc(s, chars: string) -> int {
|
|||||||
if chars == "" {
|
if chars == "" {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := len(s); i > 0; {
|
if len(s) == 1 {
|
||||||
r, w := utf8.decode_last_rune_in_string(s[:i]);
|
r := rune(s[0]);
|
||||||
i -= w;
|
if r >= utf8.RUNE_SELF {
|
||||||
for c in chars {
|
r = utf8.RUNE_ERROR;
|
||||||
if r == c {
|
}
|
||||||
|
return index_rune(chars, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s) > 8 {
|
||||||
|
if as, ok := ascii_set_make(chars); ok {
|
||||||
|
for i := len(s)-1; i >= 0; i -= 1 {
|
||||||
|
if ascii_set_contains(as, s[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(chars) == 1 {
|
||||||
|
r := rune(chars[0]);
|
||||||
|
if r >= utf8.RUNE_SELF {
|
||||||
|
r = utf8.RUNE_ERROR;
|
||||||
|
}
|
||||||
|
for i := len(s); i > 0; /**/ {
|
||||||
|
c, w := utf8.decode_last_rune_in_string(s[:i]);
|
||||||
|
i -= w;
|
||||||
|
if c == r {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := len(s); i > 0; /**/ {
|
||||||
|
r, w := utf8.decode_last_rune_in_string(s[:i]);
|
||||||
|
i -= w;
|
||||||
|
if index_rune(chars, r) >= 0 {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user