Function hasUniqueRepresentation [src]
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.
Result is always comptime-known.
Prototype
pub inline fn hasUniqueRepresentation(comptime T: type) bool
Parameters
T: type
Example
test hasUniqueRepresentation {
const TestStruct1 = struct {
a: u32,
b: u32,
};
try testing.expect(hasUniqueRepresentation(TestStruct1));
const TestStruct2 = struct {
a: u32,
b: u16,
};
try testing.expect(!hasUniqueRepresentation(TestStruct2));
const TestStruct3 = struct {
a: u32,
b: u32,
};
try testing.expect(hasUniqueRepresentation(TestStruct3));
const TestStruct4 = struct { a: []const u8 };
try testing.expect(!hasUniqueRepresentation(TestStruct4));
const TestStruct5 = struct { a: TestStruct4 };
try testing.expect(!hasUniqueRepresentation(TestStruct5));
const TestStruct6 = packed struct(u8) {
@"0": bool,
@"1": bool,
@"2": bool,
@"3": bool,
@"4": bool,
@"5": bool,
@"6": bool,
@"7": bool,
};
try testing.expect(hasUniqueRepresentation(TestStruct6));
const TestUnion1 = packed union {
a: u32,
b: u16,
};
try testing.expect(!hasUniqueRepresentation(TestUnion1));
const TestUnion2 = extern union {
a: u32,
b: u16,
};
try testing.expect(!hasUniqueRepresentation(TestUnion2));
const TestUnion3 = union {
a: u32,
b: u16,
};
try testing.expect(!hasUniqueRepresentation(TestUnion3));
const TestUnion4 = union(enum) {
a: u32,
b: u16,
};
try testing.expect(!hasUniqueRepresentation(TestUnion4));
inline for ([_]type{ i0, u8, i16, u32, i64 }) |T| {
try testing.expect(hasUniqueRepresentation(T));
}
inline for ([_]type{ i1, u9, i17, u33, i24 }) |T| {
try testing.expect(!hasUniqueRepresentation(T));
}
try testing.expect(hasUniqueRepresentation(*u8));
try testing.expect(hasUniqueRepresentation(*const u8));
try testing.expect(hasUniqueRepresentation(?*u8));
try testing.expect(hasUniqueRepresentation(?*const u8));
try testing.expect(!hasUniqueRepresentation([]u8));
try testing.expect(!hasUniqueRepresentation([]const u8));
try testing.expect(!hasUniqueRepresentation(?[]u8));
try testing.expect(!hasUniqueRepresentation(?[]const u8));
try testing.expect(hasUniqueRepresentation(@Vector(std.simd.suggestVectorLength(u8) orelse 1, u8)));
try testing.expect(@sizeOf(@Vector(3, u8)) == 3 or !hasUniqueRepresentation(@Vector(3, u8)));
const StructWithComptimeFields = struct {
comptime should_be_ignored: u64 = 42,
comptime should_also_be_ignored: [*:0]const u8 = "hope you're having a good day :)",
field: u32,
};
try testing.expect(hasUniqueRepresentation(StructWithComptimeFields));
}
Source
pub inline fn hasUniqueRepresentation(comptime T: type) bool {
return switch (@typeInfo(T)) {
else => false, // TODO can we know if it's true for some of these types ?
.@"anyframe",
.@"enum",
.error_set,
.@"fn",
=> true,
.bool => false,
.int => |info| @sizeOf(T) * 8 == info.bits,
.pointer => |info| info.size != .slice,
.optional => |info| switch (@typeInfo(info.child)) {
.pointer => |ptr| !ptr.is_allowzero and switch (ptr.size) {
.slice, .c => false,
.one, .many => true,
},
else => false,
},
.array => |info| hasUniqueRepresentation(info.child),
.@"struct" => |info| {
if (info.layout == .@"packed") return @sizeOf(T) * 8 == @bitSizeOf(T);
var sum_size = @as(usize, 0);
inline for (info.fields) |field| {
if (field.is_comptime) continue;
if (!hasUniqueRepresentation(field.type)) return false;
sum_size += @sizeOf(field.type);
}
return @sizeOf(T) == sum_size;
},
.vector => |info| hasUniqueRepresentation(info.child) and
@sizeOf(T) == @sizeOf(info.child) * info.len,
};
}