authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-04-01 01:44:14+11:00
committergravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-04-01 01:44:55+11:00
logb1eb831aba6eec78f367053200007c867817e811
tree5c68f9a6c72ba03dc8dc8240e99040a3ce59087a
parentd57b5205c61d1110745484cbade5fcac51835023
signaturelock-open Commit is signed but in an unrecognized format.

std: fix mem.span* when an optional pointer is passed


1 files changed, 16 insertions(+), 6 deletions(-)

lib/std/mem.zig+16-6
...@@ -559,10 +559,14 @@ test "Span" {...@@ -559,10 +559,14 @@ test "Span" {
559/// When there is both a sentinel and an array length or slice length, the559/// When there is both a sentinel and an array length or slice length, the
560/// length value is used instead of the sentinel.560/// length value is used instead of the sentinel.
561pub fn span(ptr: var) Span(@TypeOf(ptr)) {561pub fn span(ptr: var) Span(@TypeOf(ptr)) {
562 const Result = Span(@TypeOf(ptr));562 if (@typeInfo(@TypeOf(ptr)) == .Optional) {
563 if (@typeInfo(@TypeOf(ptr)) == .Optional and ptr == null) {563 if (ptr) |non_null| {
564 return null;564 return span(non_null);
565 } else {
566 return null;
567 }
565 }568 }
569 const Result = Span(@TypeOf(ptr));
566 const l = len(ptr);570 const l = len(ptr);
567 if (@typeInfo(Result).Pointer.sentinel) |s| {571 if (@typeInfo(Result).Pointer.sentinel) |s| {
568 return ptr[0..l :s];572 return ptr[0..l :s];
...@@ -576,16 +580,21 @@ test "span" {...@@ -576,16 +580,21 @@ test "span" {
576 const ptr = @as([*:3]u16, array[0..2 :3]);580 const ptr = @as([*:3]u16, array[0..2 :3]);
577 testing.expect(eql(u16, span(ptr), &[_]u16{ 1, 2 }));581 testing.expect(eql(u16, span(ptr), &[_]u16{ 1, 2 }));
578 testing.expect(eql(u16, span(&array), &[_]u16{ 1, 2, 3, 4, 5 }));582 testing.expect(eql(u16, span(&array), &[_]u16{ 1, 2, 3, 4, 5 }));
583 testing.expectEqual(@as(?[:0]u16, null), span(@as(?[*:0]u16, null)));
579}584}
580585
581/// Same as `span`, except when there is both a sentinel and an array586/// Same as `span`, except when there is both a sentinel and an array
582/// length or slice length, scans the memory for the sentinel value587/// length or slice length, scans the memory for the sentinel value
583/// rather than using the length.588/// rather than using the length.
584pub fn spanZ(ptr: var) Span(@TypeOf(ptr)) {589pub fn spanZ(ptr: var) Span(@TypeOf(ptr)) {
585 const Result = Span(@TypeOf(ptr));590 if (@typeInfo(@TypeOf(ptr)) == .Optional) {
586 if (@typeInfo(@TypeOf(ptr)) == .Optional and ptr == null) {591 if (ptr) |non_null| {
587 return null;592 return spanZ(non_null);
593 } else {
594 return null;
595 }
588 }596 }
597 const Result = Span(@TypeOf(ptr));
589 const l = lenZ(ptr);598 const l = lenZ(ptr);
590 if (@typeInfo(Result).Pointer.sentinel) |s| {599 if (@typeInfo(Result).Pointer.sentinel) |s| {
591 return ptr[0..l :s];600 return ptr[0..l :s];
...@@ -599,6 +608,7 @@ test "spanZ" {...@@ -599,6 +608,7 @@ test "spanZ" {
599 const ptr = @as([*:3]u16, array[0..2 :3]);608 const ptr = @as([*:3]u16, array[0..2 :3]);
600 testing.expect(eql(u16, spanZ(ptr), &[_]u16{ 1, 2 }));609 testing.expect(eql(u16, spanZ(ptr), &[_]u16{ 1, 2 }));
601 testing.expect(eql(u16, spanZ(&array), &[_]u16{ 1, 2, 3, 4, 5 }));610 testing.expect(eql(u16, spanZ(&array), &[_]u16{ 1, 2, 3, 4, 5 }));
611 testing.expectEqual(@as(?[:0]u16, null), spanZ(@as(?[*:0]u16, null)));
602}612}
603613
604/// Takes a pointer to an array, an array, a sentinel-terminated pointer,614/// Takes a pointer to an array, an array, a sentinel-terminated pointer,