ona/source/coral/math.zig

49 lines
1.3 KiB
Zig
Raw Normal View History

2023-05-23 02:08:34 +02:00
const std = @import("std");
2023-07-22 14:57:39 +02:00
pub fn Int(comptime int: std.builtin.Type.Int) type {
return @Type(.{.Int = int});
}
pub fn clamp(value: anytype, lower: anytype, upper: anytype) @TypeOf(value, lower, upper) {
return @max(lower, @min(upper, value));
}
pub fn clamped_cast(comptime dest_int: std.builtin.Type.Int, value: anytype) Int(dest_int) {
const Value = @TypeOf(value);
return switch (@typeInfo(Value)) {
.Int => |int| switch (int.signedness) {
.signed => @intCast(clamp(value, min_int(dest_int), max_int(dest_int))),
.unsigned => @intCast(@min(value, max_int(dest_int))),
},
else => @compileError("`" ++ @typeName(Value) ++ "` cannot be cast to an int"),
};
2023-05-23 02:08:34 +02:00
}
pub fn max_int(comptime int: std.builtin.Type.Int) comptime_int {
const bit_count = int.bits;
2023-04-19 01:25:35 +02:00
if (bit_count == 0) return 0;
2023-07-10 02:10:56 +02:00
return (1 << (bit_count - @intFromBool(int.signedness == .signed))) - 1;
2023-04-19 01:25:35 +02:00
}
2023-05-23 02:08:34 +02:00
pub fn min_int(comptime int: std.builtin.Type.Int) comptime_int {
2023-07-22 15:44:33 +02:00
if (int.signedness == .unsigned) {
return 0;
}
2023-05-23 02:08:34 +02:00
const bit_count = int.bits;
if (bit_count == 0) return 0;
2023-07-22 15:44:33 +02:00
return -(1 << (bit_count - 1));
2023-04-19 01:25:35 +02:00
}
2023-05-24 01:22:12 +02:00
pub fn wrap(value: anytype, lower: anytype, upper: anytype) @TypeOf(value, lower, upper) {
const range = upper - lower;
return if (range == 0) lower else lower + @mod((@mod((value - lower), range) + range), range);
}