浏览代码

Merge pull request #562 from Tetralux/string-compare

Fix #552: Fix strings.compare for empty strings and different-length strings.
gingerBill 5 年之前
父节点
当前提交
49ecd73406
共有 2 个文件被更改,包括 13 次插入1 次删除
  1. 11 1
      core/mem/mem.odin
  2. 2 0
      core/strings/strings.odin

+ 11 - 1
core/mem/mem.odin

@@ -45,8 +45,18 @@ copy_non_overlapping :: proc "contextless" (dst, src: rawptr, len: int) -> rawpt
 	return runtime.mem_copy_non_overlapping(dst, src, len);
 }
 compare :: inline proc "contextless" (a, b: []byte) -> int {
-	return compare_byte_ptrs(&a[0], &b[0], min(len(a), len(b)));
+	// NOTE(tetra): no-abc is okay here because if the slices are empty, `&a[0]` is just nil+0 == nil, which
+	// compare_byte_ptrs handles fine when the passed length is also zero.
+	res := #no_bounds_check compare_byte_ptrs(&a[0], &b[0], min(len(a), len(b)));
+	if res == 0 && len(a) != len(b) {
+		return len(a) <= len(b) ? -1 : +1;
+	} else if len(a) == 0 && len(b) == 0 {
+		return 0;
+	} else {
+		return res;
+	}
 }
+
 compare_byte_ptrs :: proc "contextless" (a, b: ^byte, n: int) -> int #no_bounds_check {
 	x := slice_ptr(a, n);
 	y := slice_ptr(b, n);

+ 2 - 0
core/strings/strings.odin

@@ -52,6 +52,8 @@ unsafe_string_to_cstring :: proc(str: string) -> cstring {
 	return cstring(d.data);
 }
 
+// Compares two strings, returning a value representing which one comes first lexiographically.
+// -1 for `a`; 1 for `b`, or 0 if they are equal.
 compare :: proc(lhs, rhs: string) -> int {
 	return mem.compare(transmute([]byte)lhs, transmute([]byte)rhs);
 }