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