From 7ae1b3a6b348a24f07bacb6e19f1aa6d7b3ba32d Mon Sep 17 00:00:00 2001 From: Sahnvour Date: Sun, 26 Jul 2020 22:01:33 +0200 Subject: [PATCH] add trait hasUniqueRepresentation --- lib/std/meta/trait.zig | 68 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/lib/std/meta/trait.zig b/lib/std/meta/trait.zig index 5cea0ecb9a..7414edac4f 100644 --- a/lib/std/meta/trait.zig +++ b/lib/std/meta/trait.zig @@ -416,3 +416,71 @@ test "std.meta.trait.hasFunctions" { testing.expect(!hasFunctions(TestStruct2, .{ "a", "b", "c" })); testing.expect(!hasFunctions(TestStruct2, tuple)); } + +/// True if every value of the type `T` has a unique bit pattern representing it. +/// In other words, `T` has no unused bits and no padding. +pub fn hasUniqueRepresentation(comptime T: type) bool { + switch (@typeInfo(T)) { + else => return false, // TODO can we know if it's true for some of these types ? + + .AnyFrame, + .Bool, + .BoundFn, + .Enum, + .ErrorSet, + .Fn, + .Int, // TODO check that it is still true + .Pointer, + => return true, + + .Array => |info| return comptime hasUniqueRepresentation(info.child), + + .Struct => |info| { + var sum_size = @as(usize, 0); + + inline for (info.fields) |field| { + const FieldType = field.field_type; + if (comptime !hasUniqueRepresentation(FieldType)) return false; + sum_size += @sizeOf(FieldType); + } + + return @sizeOf(T) == sum_size; + }, + + .Vector => |info| return comptime hasUniqueRepresentation(info.child), + } +} + +test "std.meta.trait.hasUniqueRepresentation" { + const TestStruct1 = struct { + a: u32, + b: u32, + }; + + testing.expect(hasUniqueRepresentation(TestStruct1)); + + const TestStruct2 = struct { + a: u32, + b: u16, + }; + + testing.expect(!hasUniqueRepresentation(TestStruct2)); + + const TestStruct3 = struct { + a: u32, + b: u32, + }; + + testing.expect(hasUniqueRepresentation(TestStruct3)); + + testing.expect(hasUniqueRepresentation(i1)); + testing.expect(hasUniqueRepresentation(u2)); + testing.expect(hasUniqueRepresentation(i3)); + testing.expect(hasUniqueRepresentation(u4)); + testing.expect(hasUniqueRepresentation(i5)); + testing.expect(hasUniqueRepresentation(u6)); + testing.expect(hasUniqueRepresentation(i7)); + testing.expect(hasUniqueRepresentation(u8)); + testing.expect(hasUniqueRepresentation(i9)); + testing.expect(hasUniqueRepresentation(u10)); +}