feature. See also
. The project being documented here (as the example) is the Zig library itself.
ff.ct_protected
const ct_protected = struct
File
Code
const ct_protected = struct {
fn select(on: bool, x: Limb, y: Limb) Limb {
const mask = @as(Limb, 0) -% @intFromBool(on);
return y ^ (mask & (y ^ x));
}
fn eql(x: anytype, y: @TypeOf(x)) bool {
const c1 = @subWithOverflow(x, y)[1];
const c2 = @subWithOverflow(y, x)[1];
return @as(bool, @bitCast(1 - (c1 | c2)));
}
fn limbsCmpLt(x: anytype, y: @TypeOf(x)) bool {
var c: u1 = 0;
for (x.limbsConst(), y.limbsConst()) |x_limb, y_limb| {
c = @truncate((x_limb -% y_limb -% c) >> t_bits);
}
return c != 0;
}
fn limbsCmpGeq(x: anytype, y: @TypeOf(x)) bool {
return !limbsCmpLt(x, y);
}
fn mulWide(x: Limb, y: Limb) WideLimb {
const half_bits = @typeInfo(Limb).int.bits / 2;
const Half = @Int(.unsigned, half_bits);
const x0 = @as(Half, @truncate(x));
const x1 = @as(Half, @truncate(x >> half_bits));
const y0 = @as(Half, @truncate(y));
const y1 = @as(Half, @truncate(y >> half_bits));
const w0 = math.mulWide(Half, x0, y0);
const t = math.mulWide(Half, x1, y0) + (w0 >> half_bits);
var w1: Limb = @as(Half, @truncate(t));
const w2 = @as(Half, @truncate(t >> half_bits));
w1 += math.mulWide(Half, x0, y1);
const hi = math.mulWide(Half, x1, y1) + w2 + (w1 >> half_bits);
const lo = x *% y;
return .{ .hi = hi, .lo = lo };
}
}