authorgravatar for data-man@users.noreply.github.comDmitry Atamanov <data-man@users.noreply.github.com> 2020-08-14 03:14:32+05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-08-14 01:14:32+03:00
loga9590f3bf863493ed9b15ad8ab0d4fa7991805a5
tree88ced28707f254726b6266c41c54955ec98e0eba
parentf5b99abc93b44239e95378d9958e72999abb6b44
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Support tuples in mem.len and trait.isIndexable (#5897)


2 files changed, 12 insertions(+), 2 deletions(-)

lib/std/mem.zig+9-1
...@@ -614,7 +614,7 @@ test "spanZ" {...@@ -614,7 +614,7 @@ test "spanZ" {
614}614}
615615
616/// Takes a pointer to an array, an array, a vector, a sentinel-terminated pointer,616/// Takes a pointer to an array, an array, a vector, a sentinel-terminated pointer,
617/// or a slice, and returns the length.617/// a slice or a tuple, and returns the length.
618/// In the case of a sentinel-terminated array, it uses the array length.618/// In the case of a sentinel-terminated array, it uses the array length.
619/// For C pointers it assumes it is a pointer-to-many with a 0 sentinel.619/// For C pointers it assumes it is a pointer-to-many with a 0 sentinel.
620pub fn len(value: anytype) usize {620pub fn len(value: anytype) usize {
...@@ -633,6 +633,9 @@ pub fn len(value: anytype) usize {...@@ -633,6 +633,9 @@ pub fn len(value: anytype) usize {
633 .C => indexOfSentinel(info.child, 0, value),633 .C => indexOfSentinel(info.child, 0, value),
634 .Slice => value.len,634 .Slice => value.len,
635 },635 },
636 .Struct => |info| if (info.is_tuple) {
637 return info.fields.len;
638 } else @compileError("invalid type given to std.mem.len"),
636 else => @compileError("invalid type given to std.mem.len"),639 else => @compileError("invalid type given to std.mem.len"),
637 };640 };
638}641}
...@@ -658,6 +661,11 @@ test "len" {...@@ -658,6 +661,11 @@ test "len" {
658 const vector: meta.Vector(2, u32) = [2]u32{ 1, 2 };661 const vector: meta.Vector(2, u32) = [2]u32{ 1, 2 };
659 testing.expect(len(vector) == 2);662 testing.expect(len(vector) == 2);
660 }663 }
664 {
665 const tuple = .{ 1, 2 };
666 testing.expect(len(tuple) == 2);
667 testing.expect(tuple[0] == 1);
668 }
661}669}
662670
663/// Takes a pointer to an array, an array, a sentinel-terminated pointer,671/// Takes a pointer to an array, an array, a sentinel-terminated pointer,
lib/std/meta/trait.zig+3-1
...@@ -269,19 +269,21 @@ pub fn isIndexable(comptime T: type) bool {...@@ -269,19 +269,21 @@ pub fn isIndexable(comptime T: type) bool {
269 }269 }
270 return true;270 return true;
271 }271 }
272 return comptime is(.Array)(T) or is(.Vector)(T);272 return comptime is(.Array)(T) or is(.Vector)(T) or isTuple(T);
273}273}
274274
275test "std.meta.trait.isIndexable" {275test "std.meta.trait.isIndexable" {
276 const array = [_]u8{0} ** 10;276 const array = [_]u8{0} ** 10;
277 const slice = @as([]const u8, &array);277 const slice = @as([]const u8, &array);
278 const vector: meta.Vector(2, u32) = [_]u32{0} ** 2;278 const vector: meta.Vector(2, u32) = [_]u32{0} ** 2;
279 const tuple = .{ 1, 2, 3 };
279280
280 testing.expect(isIndexable(@TypeOf(array)));281 testing.expect(isIndexable(@TypeOf(array)));
281 testing.expect(isIndexable(@TypeOf(&array)));282 testing.expect(isIndexable(@TypeOf(&array)));
282 testing.expect(isIndexable(@TypeOf(slice)));283 testing.expect(isIndexable(@TypeOf(slice)));
283 testing.expect(!isIndexable(meta.Child(@TypeOf(slice))));284 testing.expect(!isIndexable(meta.Child(@TypeOf(slice))));
284 testing.expect(isIndexable(@TypeOf(vector)));285 testing.expect(isIndexable(@TypeOf(vector)));
286 testing.expect(isIndexable(@TypeOf(tuple)));
285}287}
286288
287pub fn isNumber(comptime T: type) bool {289pub fn isNumber(comptime T: type) bool {