aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorJordan Lewis <jordanthelewis@gmail.com>2022-12-28 14:27:18 -0500
committerVeikka Tuominen <git@vexu.eu>2023-01-03 13:30:24 +0200
commit1ec74f1b70607a17829277e846ea19be6aed1fc1 (patch)
treefce91f172fe18842908aca8a8edb12969e62c6a9 /lib/std
parentfc07e1a2670970084bfaac726428f6f3392abf30 (diff)
downloadzig-1ec74f1b70607a17829277e846ea19be6aed1fc1.tar.gz
zig-1ec74f1b70607a17829277e846ea19be6aed1fc1.zip
math: implement absInt for integer vectors
This commit adds support to absInt for integer vectors.
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/math.zig38
1 files changed, 29 insertions, 9 deletions
diff --git a/lib/std/math.zig b/lib/std/math.zig
index 00f86fab1b..c8eff2362e 100644
--- a/lib/std/math.zig
+++ b/lib/std/math.zig
@@ -784,15 +784,31 @@ fn testOverflow() !void {
/// See also: `absCast`
pub fn absInt(x: anytype) !@TypeOf(x) {
const T = @TypeOf(x);
- comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
- comptime assert(@typeInfo(T).Int.signedness == .signed); // must pass a signed integer to absInt
-
- if (x == minInt(T)) {
- return error.Overflow;
- } else {
- @setRuntimeSafety(false);
- return if (x < 0) -x else x;
- }
+ return switch (@typeInfo(T)) {
+ .Int => |info| {
+ comptime assert(info.signedness == .signed); // must pass a signed integer to absInt
+ if (x == minInt(T)) {
+ return error.Overflow;
+ } else {
+ @setRuntimeSafety(false);
+ return if (x < 0) -x else x;
+ }
+ },
+ .Vector => |vinfo| blk: {
+ switch (@typeInfo(vinfo.child)) {
+ .Int => |info| {
+ comptime assert(info.signedness == .signed); // must pass a signed integer to absInt
+ if (@reduce(.Or, x == @splat(vinfo.len, @as(vinfo.child, minInt(vinfo.child))))) {
+ return error.Overflow;
+ }
+ const zero = @splat(vinfo.len, @as(vinfo.child, 0));
+ break :blk @select(vinfo.child, x > zero, x, -x);
+ },
+ else => @compileError("Expected vector of ints, found " ++ @typeName(T)),
+ }
+ },
+ else => @compileError("Expected an int or vector, found " ++ @typeName(T)),
+ };
}
test "absInt" {
@@ -802,6 +818,10 @@ test "absInt" {
fn testAbsInt() !void {
try testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10);
try testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10);
+ try testing.expectEqual(@Vector(3, i32){ 10, 10, 0 }, (absInt(@Vector(3, i32){ -10, 10, 0 }) catch unreachable));
+
+ try testing.expectError(error.Overflow, absInt(@as(i32, minInt(i32))));
+ try testing.expectError(error.Overflow, absInt(@Vector(3, i32){ 10, -10, minInt(i32) }));
}
/// Divide numerator by denominator, rounding toward zero. Returns an