Browse Source

Merge pull request #1849 from Kelimion/prefix_length

Add `strings.prefix_length` & `slice.prefix_length`
Jeroen van Rijn 3 years ago
parent
commit
9b7710488b
2 changed files with 38 additions and 0 deletions
  1. 15 0
      core/slice/slice.odin
  2. 23 0
      core/strings/strings.odin

+ 15 - 0
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 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) {
 has_prefix :: proc(array: $T/[]$E, needle: E) -> bool where intrinsics.type_is_comparable(E) {
 	n := len(needle)
 	n := len(needle)

+ 23 - 0
core/strings/strings.odin

@@ -215,6 +215,29 @@ equal_fold :: proc(u, v: string) -> bool {
 	return s == t
 	return s == t
 }
 }
 
 
+/*
+	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`
 	return true when the string `prefix` is contained at the start of the string `s`