Commit a9590f3bf8

Dmitry Atamanov <data-man@users.noreply.github.com>
2020-08-14 00:14:32
Support tuples in mem.len and trait.isIndexable (#5897)
1 parent f5b99ab
Changed files (2)
lib
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 {
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,