From a9590f3bf863493ed9b15ad8ab0d4fa7991805a5 Mon Sep 17 00:00:00 2001 From: Dmitry Atamanov Date: Fri, 14 Aug 2020 03:14:32 +0500 Subject: [PATCH] Support tuples in mem.len and trait.isIndexable (#5897) --- lib/std/mem.zig | 10 +++++++++- lib/std/meta/trait.zig | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 5a0927ea6e..1ba64f47fa 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -614,7 +614,7 @@ test "spanZ" { } /// Takes a pointer to an array, an array, a vector, a sentinel-terminated pointer, -/// or a slice, and returns the length. +/// a slice or a tuple, and returns the length. /// In the case of a sentinel-terminated array, it uses the array length. /// For C pointers it assumes it is a pointer-to-many with a 0 sentinel. pub fn len(value: anytype) usize { @@ -633,6 +633,9 @@ pub fn len(value: anytype) usize { .C => indexOfSentinel(info.child, 0, value), .Slice => value.len, }, + .Struct => |info| if (info.is_tuple) { + return info.fields.len; + } else @compileError("invalid type given to std.mem.len"), else => @compileError("invalid type given to std.mem.len"), }; } @@ -658,6 +661,11 @@ test "len" { const vector: meta.Vector(2, u32) = [2]u32{ 1, 2 }; testing.expect(len(vector) == 2); } + { + const tuple = .{ 1, 2 }; + testing.expect(len(tuple) == 2); + testing.expect(tuple[0] == 1); + } } /// Takes a pointer to an array, an array, a sentinel-terminated pointer, diff --git a/lib/std/meta/trait.zig b/lib/std/meta/trait.zig index 1aa5455bb5..f04d6353c6 100644 --- a/lib/std/meta/trait.zig +++ b/lib/std/meta/trait.zig @@ -269,19 +269,21 @@ pub fn isIndexable(comptime T: type) bool { } return true; } - return comptime is(.Array)(T) or is(.Vector)(T); + return comptime is(.Array)(T) or is(.Vector)(T) or isTuple(T); } test "std.meta.trait.isIndexable" { const array = [_]u8{0} ** 10; const slice = @as([]const u8, &array); const vector: meta.Vector(2, u32) = [_]u32{0} ** 2; + const tuple = .{ 1, 2, 3 }; testing.expect(isIndexable(@TypeOf(array))); testing.expect(isIndexable(@TypeOf(&array))); testing.expect(isIndexable(@TypeOf(slice))); testing.expect(!isIndexable(meta.Child(@TypeOf(slice)))); testing.expect(isIndexable(@TypeOf(vector))); + testing.expect(isIndexable(@TypeOf(tuple))); } pub fn isNumber(comptime T: type) bool {