Skip to content

Commit 1ec74f1

Browse files
jordanlewisVexu
authored andcommitted
math: implement absInt for integer vectors
This commit adds support to absInt for integer vectors.
1 parent fc07e1a commit 1ec74f1

1 file changed

Lines changed: 29 additions & 9 deletions

File tree

lib/std/math.zig

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -784,15 +784,31 @@ fn testOverflow() !void {
784784
/// See also: `absCast`
785785
pub fn absInt(x: anytype) !@TypeOf(x) {
786786
const T = @TypeOf(x);
787-
comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
788-
comptime assert(@typeInfo(T).Int.signedness == .signed); // must pass a signed integer to absInt
789-
790-
if (x == minInt(T)) {
791-
return error.Overflow;
792-
} else {
793-
@setRuntimeSafety(false);
794-
return if (x < 0) -x else x;
795-
}
787+
return switch (@typeInfo(T)) {
788+
.Int => |info| {
789+
comptime assert(info.signedness == .signed); // must pass a signed integer to absInt
790+
if (x == minInt(T)) {
791+
return error.Overflow;
792+
} else {
793+
@setRuntimeSafety(false);
794+
return if (x < 0) -x else x;
795+
}
796+
},
797+
.Vector => |vinfo| blk: {
798+
switch (@typeInfo(vinfo.child)) {
799+
.Int => |info| {
800+
comptime assert(info.signedness == .signed); // must pass a signed integer to absInt
801+
if (@reduce(.Or, x == @splat(vinfo.len, @as(vinfo.child, minInt(vinfo.child))))) {
802+
return error.Overflow;
803+
}
804+
const zero = @splat(vinfo.len, @as(vinfo.child, 0));
805+
break :blk @select(vinfo.child, x > zero, x, -x);
806+
},
807+
else => @compileError("Expected vector of ints, found " ++ @typeName(T)),
808+
}
809+
},
810+
else => @compileError("Expected an int or vector, found " ++ @typeName(T)),
811+
};
796812
}
797813

798814
test "absInt" {
@@ -802,6 +818,10 @@ test "absInt" {
802818
fn testAbsInt() !void {
803819
try testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10);
804820
try testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10);
821+
try testing.expectEqual(@Vector(3, i32){ 10, 10, 0 }, (absInt(@Vector(3, i32){ -10, 10, 0 }) catch unreachable));
822+
823+
try testing.expectError(error.Overflow, absInt(@as(i32, minInt(i32))));
824+
try testing.expectError(error.Overflow, absInt(@Vector(3, i32){ 10, -10, minInt(i32) }));
805825
}
806826

807827
/// Divide numerator by denominator, rounding toward zero. Returns an

0 commit comments

Comments
 (0)