Stored as a power-of-two.
pub const Alignment = enum(math.Log2Int(usize))
pub const Alignment = enum(math.Log2Int(usize)) {
@"1" = 0,
@"2" = 1,
@"4" = 2,
@"8" = 3,
@"16" = 4,
@"32" = 5,
@"64" = 6,
_,
pub fn toByteUnits(a: Alignment) usize {
return @as(usize, 1) << @backingInt(a);
}
pub fn fromByteUnits(n: usize) Alignment {
assert(std.math.isPowerOfTwo(n));
return @fromBackingInt(@intCast(@ctz(n)));
}
pub fn fromByteUnitsOptional(maybe_n: ?usize) ?Alignment {
return if (maybe_n) |n| .fromByteUnits(n) else null;
}
pub inline fn of(comptime T: type) Alignment {
return comptime fromByteUnits(@alignOf(T));
}
pub fn order(lhs: Alignment, rhs: Alignment) std.math.Order {
return std.math.order(@backingInt(lhs), @backingInt(rhs));
}
pub fn compare(lhs: Alignment, op: std.math.CompareOperator, rhs: Alignment) bool {
return std.math.compare(@backingInt(lhs), op, @backingInt(rhs));
}
pub fn max(lhs: Alignment, rhs: Alignment) Alignment {
return @fromBackingInt(@intCast(@max(@backingInt(lhs), @backingInt(rhs))));
}
pub fn min(lhs: Alignment, rhs: Alignment) Alignment {
return @fromBackingInt(@intCast(@min(@backingInt(lhs), @backingInt(rhs))));
}
/// Return next address with this alignment.
pub fn forward(a: Alignment, address: usize) usize {
const x = (@as(usize, 1) << @backingInt(a)) - 1;
return (address + x) & ~x;
}
/// Return previous address with this alignment.
pub fn backward(a: Alignment, address: usize) usize {
const x = (@as(usize, 1) << @backingInt(a)) - 1;
return address & ~x;
}
/// Return whether address is aligned to this amount.
pub fn check(a: Alignment, address: usize) bool {
return @ctz(address) >= @backingInt(a);
}
}