std.hash: auto hash signed ints as bitcasts of unsigned ints

This commit is contained in:
Andrew Kelley 2023-06-01 23:45:36 -07:00
parent e0179640d5
commit 34dae73005

View File

@ -91,15 +91,21 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
// Help the optimizer see that hashing an int is easy by inlining!
// TODO Check if the situation is better after #561 is resolved.
.Int => {
if (comptime meta.trait.hasUniqueRepresentation(Key)) {
@call(.always_inline, Hasher.update, .{ hasher, std.mem.asBytes(&key) });
} else {
// Take only the part containing the key value, the remaining
// bytes are undefined and must not be hashed!
const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable;
@call(.always_inline, Hasher.update, .{ hasher, std.mem.asBytes(&key)[0..byte_size] });
}
.Int => |int| switch (int.signedness) {
.signed => hash(hasher, @bitCast(@Type(.{ .Int = .{
.bits = int.bits,
.signedness = .unsigned,
} }), key), strat),
.unsigned => {
if (comptime meta.trait.hasUniqueRepresentation(Key)) {
@call(.always_inline, Hasher.update, .{ hasher, std.mem.asBytes(&key) });
} else {
// Take only the part containing the key value, the remaining
// bytes are undefined and must not be hashed!
const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable;
@call(.always_inline, Hasher.update, .{ hasher, std.mem.asBytes(&key)[0..byte_size] });
}
},
},
.Bool => hash(hasher, @boolToInt(key), strat),