aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-03-15 15:46:56 -0400
committerAndrew Kelley <andrew@ziglang.org>2020-03-15 15:46:56 -0400
commit6c2b23593b97aef6f375bd7d81beeaf0f66f5682 (patch)
tree928e581db83b81c6799063335c2ce605e308f7b1 /lib/std
parent701aaf0ddf618edffa182db1e888172b6cae4ab1 (diff)
downloadzig-6c2b23593b97aef6f375bd7d81beeaf0f66f5682.tar.gz
zig-6c2b23593b97aef6f375bd7d81beeaf0f66f5682.zip
fix std.mem.span handling of sentinel-terminated arrays
previously this function would use the array length, but now it scans the array looking for the first sentinel that occurs.
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/mem.zig18
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index c767765652..07fbebfb3b 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -567,12 +567,20 @@ test "span" {
/// Takes a pointer to an array, an array, a sentinel-terminated pointer,
/// or a slice, and returns the length.
+/// In the case of a sentinel-terminated array, it scans the array
+/// for a sentinel and uses that for the length, rather than using the array length.
pub fn len(ptr: var) usize {
return switch (@typeInfo(@TypeOf(ptr))) {
- .Array => |info| info.len,
+ .Array => |info| if (info.sentinel) |sentinel|
+ indexOfSentinel(info.child, sentinel, &ptr)
+ else
+ info.len,
.Pointer => |info| switch (info.size) {
.One => switch (@typeInfo(info.child)) {
- .Array => |x| x.len,
+ .Array => |x| if (x.sentinel) |sentinel|
+ indexOfSentinel(x.child, sentinel, ptr)
+ else
+ ptr.len,
else => @compileError("invalid type given to std.mem.length"),
},
.Many => if (info.sentinel) |sentinel|
@@ -597,6 +605,12 @@ test "len" {
const ptr = array[0..2 :0].ptr;
testing.expect(len(ptr) == 2);
}
+ {
+ var array: [5:0]u16 = [_]u16{ 1, 2, 3, 4, 5 };
+ testing.expect(len(&array) == 5);
+ array[2] = 0;
+ testing.expect(len(&array) == 2);
+ }
}
pub fn indexOfSentinel(comptime Elem: type, comptime sentinel: Elem, ptr: [*:sentinel]const Elem) usize {