Function compare [src]
Compare two integers serialized as arrays of the same size, in constant time.
Returns .lt if ab and .eq if a=b
Prototype
pub fn compare(comptime T: type, a: []const T, b: []const T, endian: Endian) Order
Parameters
T: type
a: []const T
b: []const T
endian: Endian
Example
test compare {
const expectEqual = std.testing.expectEqual;
var a = [_]u8{10} ** 32;
var b = [_]u8{10} ** 32;
try expectEqual(compare(u8, &a, &b, .big), .eq);
try expectEqual(compare(u8, &a, &b, .little), .eq);
a[31] = 1;
try expectEqual(compare(u8, &a, &b, .big), .lt);
try expectEqual(compare(u8, &a, &b, .little), .lt);
a[0] = 20;
try expectEqual(compare(u8, &a, &b, .big), .gt);
try expectEqual(compare(u8, &a, &b, .little), .lt);
}
Source
pub fn compare(comptime T: type, a: []const T, b: []const T, endian: Endian) Order {
assert(a.len == b.len);
const bits = switch (@typeInfo(T)) {
.int => |cinfo| if (cinfo.signedness != .unsigned) @compileError("Elements to be compared must be unsigned") else cinfo.bits,
else => @compileError("Elements to be compared must be integers"),
};
const Cext = std.meta.Int(.unsigned, bits + 1);
var gt: T = 0;
var eq: T = 1;
if (endian == .little) {
var i = a.len;
while (i != 0) {
i -= 1;
const x1 = a[i];
const x2 = b[i];
gt |= @as(T, @truncate((@as(Cext, x2) -% @as(Cext, x1)) >> bits)) & eq;
eq &= @as(T, @truncate((@as(Cext, (x2 ^ x1)) -% 1) >> bits));
}
} else {
for (a, 0..) |x1, i| {
const x2 = b[i];
gt |= @as(T, @truncate((@as(Cext, x2) -% @as(Cext, x1)) >> bits)) & eq;
eq &= @as(T, @truncate((@as(Cext, (x2 ^ x1)) -% 1) >> bits));
}
}
if (gt != 0) {
return Order.gt;
} else if (eq != 0) {
return Order.eq;
}
return Order.lt;
}