2016-12-18 14:24:52 -08:00
|
|
|
pub const Cmp = enum {
|
2016-08-11 22:25:13 -07:00
|
|
|
Equal,
|
|
|
|
Greater,
|
|
|
|
Less,
|
2016-12-18 14:24:52 -08:00
|
|
|
};
|
2016-08-11 22:25:13 -07:00
|
|
|
|
2016-09-09 05:58:39 -07:00
|
|
|
pub fn min(x: var, y: var) -> @typeOf(x + y) {
|
2016-02-02 01:43:33 -08:00
|
|
|
if (x < y) x else y
|
|
|
|
}
|
|
|
|
|
2016-09-09 05:58:39 -07:00
|
|
|
pub fn max(x: var, y: var) -> @typeOf(x + y) {
|
2016-05-08 16:05:41 -07:00
|
|
|
if (x > y) x else y
|
|
|
|
}
|
2016-07-24 18:35:50 -07:00
|
|
|
|
2016-12-17 21:25:26 -08:00
|
|
|
error Overflow;
|
2017-01-22 16:51:37 -08:00
|
|
|
pub fn mulOverflow(comptime T: type, a: T, b: T) -> %T {
|
2016-07-24 18:35:50 -07:00
|
|
|
var answer: T = undefined;
|
2016-08-16 22:42:50 -07:00
|
|
|
if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
2016-07-24 18:35:50 -07:00
|
|
|
}
|
2017-01-22 16:51:37 -08:00
|
|
|
pub fn addOverflow(comptime T: type, a: T, b: T) -> %T {
|
2016-07-24 18:35:50 -07:00
|
|
|
var answer: T = undefined;
|
2016-08-16 22:42:50 -07:00
|
|
|
if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
2016-07-24 18:35:50 -07:00
|
|
|
}
|
2017-01-22 16:51:37 -08:00
|
|
|
pub fn subOverflow(comptime T: type, a: T, b: T) -> %T {
|
2016-07-24 18:35:50 -07:00
|
|
|
var answer: T = undefined;
|
2016-08-16 22:42:50 -07:00
|
|
|
if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
2016-07-24 18:35:50 -07:00
|
|
|
}
|
2017-01-22 16:51:37 -08:00
|
|
|
pub fn shlOverflow(comptime T: type, a: T, b: T) -> %T {
|
2016-09-09 05:58:39 -07:00
|
|
|
var answer: T = undefined;
|
|
|
|
if (@shlWithOverflow(T, a, b, &answer)) error.Overflow else answer
|
|
|
|
}
|
2017-02-07 14:19:51 -08:00
|
|
|
|
|
|
|
pub fn log(comptime base: usize, value: var) -> @typeOf(value) {
|
|
|
|
const T = @typeOf(value);
|
|
|
|
if (@isInteger(T)) {
|
|
|
|
if (base == 2) {
|
|
|
|
return T.bit_count - 1 - @clz(value);
|
|
|
|
} else {
|
|
|
|
@compileError("TODO implement log for non base 2 integers");
|
|
|
|
}
|
|
|
|
} else if (@isFloat(T)) {
|
|
|
|
@compileError("TODO implement log for floats");
|
|
|
|
} else {
|
|
|
|
@compileError("log expects integer or float, found '" ++ @typeName(T) ++ "'");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// x must be an integer or a float
|
|
|
|
/// Note that this causes undefined behavior if
|
|
|
|
/// @typeOf(x).is_signed && x == @minValue(@typeOf(x)).
|
|
|
|
pub fn abs(x: var) -> @typeOf(x) {
|
|
|
|
const T = @typeOf(x);
|
|
|
|
if (@isInteger(T)) {
|
|
|
|
return if (x < 0) -x else x;
|
|
|
|
} else if (@isFloat(T)) {
|
|
|
|
@compileError("TODO implement abs for floats");
|
|
|
|
} else {
|
|
|
|
@unreachable();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fn getReturnTypeForAbs(comptime T: type) -> type {
|
|
|
|
if (@isInteger(T)) {
|
|
|
|
return @intType(false, T.bit_count);
|
|
|
|
} else {
|
|
|
|
return T;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|