aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2022-06-16 12:42:35 +0200
committerGitHub <noreply@github.com>2022-06-16 12:42:35 +0200
commit9b7710488b3f67a91687167e26faef1c9eeaa194 (patch)
tree578b00213ae32ef70547024e704a8ee2f12b2b13
parentb8802d7df769b257fcac0bc1c976e67fd1339b05 (diff)
parent9f413862e985a984773df6b6f63641f9497948be (diff)
Merge pull request #1849 from Kelimion/prefix_length
Add `strings.prefix_length` & `slice.prefix_length`
-rw-r--r--core/slice/slice.odin15
-rw-r--r--core/strings/strings.odin23
2 files changed, 38 insertions, 0 deletions
diff --git a/core/slice/slice.odin b/core/slice/slice.odin
index b8fb29ab3..440cf643f 100644
--- a/core/slice/slice.odin
+++ b/core/slice/slice.odin
@@ -170,6 +170,21 @@ simple_equal :: proc(a, b: $T/[]$E) -> bool where intrinsics.type_is_simple_comp
return mem.compare_ptrs(raw_data(a), raw_data(b), len(a)*size_of(E)) == 0
}
+/*
+ return the prefix length common between slices `a` and `b`.
+
+ slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1}) -> 1
+ slice.prefix_length([]u8{1, 2, 3, 4}, []u8{1, 2, 3}) -> 3
+ slice.prefix_length([]u8{1, 2, 3, 4}, []u8{2, 3, 4}) -> 0
+*/
+prefix_length :: proc(a, b: $T/[]$E) -> (n: int) where intrinsics.type_is_comparable(E) {
+ _len := builtin.min(len(a), len(b))
+
+ #no_bounds_check for n < _len && a[n] == b[n] {
+ n += 1
+ }
+ return
+}
has_prefix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
n := len(needle)
diff --git a/core/strings/strings.odin b/core/strings/strings.odin
index 2429b451d..678cc94cd 100644
--- a/core/strings/strings.odin
+++ b/core/strings/strings.odin
@@ -216,6 +216,29 @@ equal_fold :: proc(u, v: string) -> bool {
}
/*
+ return the prefix length common between strings `a` and `b`.
+
+ strings.prefix_length("testing", "test") -> 4
+ strings.prefix_length("testing", "te") -> 2
+ strings.prefix_length("telephone", "te") -> 2
+ strings.prefix_length("testing", "est") -> 0
+*/
+prefix_length :: proc(a, b: string) -> (n: int) {
+ _len := min(len(a), len(b))
+ idx := 0
+
+ #no_bounds_check for idx < _len && a[idx] == b[idx] {
+ idx += 1
+
+ if a[idx] & 128 != 128 {
+ // new codepoint or end of multi-byte codepoint, update match length
+ n = idx
+ }
+ }
+ return
+}
+
+/*
return true when the string `prefix` is contained at the start of the string `s`
strings.has_prefix("testing", "test") -> true