diff options
| author | Jeroen van Rijn <Kelimion@users.noreply.github.com> | 2022-06-16 12:42:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-16 12:42:35 +0200 |
| commit | 9b7710488b3f67a91687167e26faef1c9eeaa194 (patch) | |
| tree | 578b00213ae32ef70547024e704a8ee2f12b2b13 | |
| parent | b8802d7df769b257fcac0bc1c976e67fd1339b05 (diff) | |
| parent | 9f413862e985a984773df6b6f63641f9497948be (diff) | |
Merge pull request #1849 from Kelimion/prefix_length
Add `strings.prefix_length` & `slice.prefix_length`
| -rw-r--r-- | core/slice/slice.odin | 15 | ||||
| -rw-r--r-- | core/strings/strings.odin | 23 |
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 |