| ... | @@ -567,12 +567,20 @@ test "span" { | ... | @@ -567,12 +567,20 @@ test "span" { |
| 567 | | 567 | |
| 568 | /// Takes a pointer to an array, an array, a sentinel-terminated pointer, | 568 | /// Takes a pointer to an array, an array, a sentinel-terminated pointer, |
| 569 | /// or a slice, and returns the length. | 569 | /// or a slice, and returns the length. |
| | 570 | /// In the case of a sentinel-terminated array, it scans the array |
| | 571 | /// for a sentinel and uses that for the length, rather than using the array length. |
| 570 | pub fn len(ptr: var) usize { | 572 | pub fn len(ptr: var) usize { |
| 571 | return switch (@typeInfo(@TypeOf(ptr))) { | 573 | return switch (@typeInfo(@TypeOf(ptr))) { |
| 572 | .Array => |info| info.len, | 574 | .Array => |info| if (info.sentinel) |sentinel| |
| | 575 | indexOfSentinel(info.child, sentinel, &ptr) |
| | 576 | else |
| | 577 | info.len, |
| 573 | .Pointer => |info| switch (info.size) { | 578 | .Pointer => |info| switch (info.size) { |
| 574 | .One => switch (@typeInfo(info.child)) { | 579 | .One => switch (@typeInfo(info.child)) { |
| 575 | .Array => |x| x.len, | 580 | .Array => |x| if (x.sentinel) |sentinel| |
| | 581 | indexOfSentinel(x.child, sentinel, ptr) |
| | 582 | else |
| | 583 | ptr.len, |
| 576 | else => @compileError("invalid type given to std.mem.length"), | 584 | else => @compileError("invalid type given to std.mem.length"), |
| 577 | }, | 585 | }, |
| 578 | .Many => if (info.sentinel) |sentinel| | 586 | .Many => if (info.sentinel) |sentinel| |
| ... | @@ -597,6 +605,12 @@ test "len" { | ... | @@ -597,6 +605,12 @@ test "len" { |
| 597 | const ptr = array[0..2 :0].ptr; | 605 | const ptr = array[0..2 :0].ptr; |
| 598 | testing.expect(len(ptr) == 2); | 606 | testing.expect(len(ptr) == 2); |
| 599 | } | 607 | } |
| | 608 | { |
| | 609 | var array: [5:0]u16 = [_]u16{ 1, 2, 3, 4, 5 }; |
| | 610 | testing.expect(len(&array) == 5); |
| | 611 | array[2] = 0; |
| | 612 | testing.expect(len(&array) == 2); |
| | 613 | } |
| 600 | } | 614 | } |
| 601 | | 615 | |
| 602 | pub fn indexOfSentinel(comptime Elem: type, comptime sentinel: Elem, ptr: [*:sentinel]const Elem) usize { | 616 | pub fn indexOfSentinel(comptime Elem: type, comptime sentinel: Elem, ptr: [*:sentinel]const Elem) usize { |