| ... | ... | @@ -1596,9 +1596,8 @@ pub fn break_f80(x: f80) F80 { |
| 1596 | 1596 | } |
| 1597 | 1597 | |
| 1598 | 1598 | /// Returns -1, 0, or 1. |
| 1599 | | /// Supports integer types, vectors of integer types, and float types. |
| 1599 | /// Supports integer and float types and vectors of integer and float types. |
| 1600 | 1600 | /// Unsigned integer types will always return 0 or 1. |
| 1601 | | /// TODO: support vectors of floats |
| 1602 | 1601 | /// Branchless. |
| 1603 | 1602 | pub inline fn sign(i: anytype) @TypeOf(i) { |
| 1604 | 1603 | const T = @TypeOf(i); |
| ... | ... | @@ -1606,15 +1605,14 @@ pub inline fn sign(i: anytype) @TypeOf(i) { |
| 1606 | 1605 | .Int, .ComptimeInt => @as(T, @boolToInt(i > 0)) - @boolToInt(i < 0), |
| 1607 | 1606 | .Float, .ComptimeFloat => @intToFloat(T, @boolToInt(i > 0)) - @intToFloat(T, @boolToInt(i < 0)), |
| 1608 | 1607 | .Vector => |vinfo| blk: { |
| 1609 | | const u1xN = std.meta.Vector(vinfo.len, u1); |
| 1610 | | break :blk switch (@typeInfo(vinfo.child)) { |
| 1611 | | .Int => @as(T, @bitCast(u1xN, i > @splat(vinfo.len, @as(vinfo.child, 0)))) - |
| 1612 | | @as(T, @bitCast(u1xN, i < @splat(vinfo.len, @as(vinfo.child, 0)))), |
| 1613 | | .Float => @compileError("TODO: add support for vectors of floats once @intToFloat accepts vector types"), |
| 1614 | | // break :blk @intToFloat(T, @bitCast(u1xN, i > @splat(vinfo.len, @as(vinfo.child, 0)))) - |
| 1615 | | // @intToFloat(T, @bitCast(u1xN, i < @splat(vinfo.len, @as(vinfo.child, 0)))), |
| 1608 | switch (@typeInfo(vinfo.child)) { |
| 1609 | .Int, .Float => { |
| 1610 | const zero = @splat(vinfo.len, @as(vinfo.child, 0)); |
| 1611 | const one = @splat(vinfo.len, @as(vinfo.child, 1)); |
| 1612 | break :blk @select(vinfo.child, i > zero, one, zero) - @select(vinfo.child, i < zero, one, zero); |
| 1613 | }, |
| 1616 | 1614 | else => @compileError("Expected vector of ints or floats, found " ++ @typeName(T)), |
| 1617 | | }; |
| 1615 | } |
| 1618 | 1616 | }, |
| 1619 | 1617 | else => @compileError("Expected an int, float or vector of one, found " ++ @typeName(T)), |
| 1620 | 1618 | }; |
| ... | ... | @@ -1669,24 +1667,21 @@ fn testSign() !void { |
| 1669 | 1667 | try std.testing.expectEqual(@as(T, 1), sign(@as(T, 2))); |
| 1670 | 1668 | try std.testing.expectEqual(@as(T, -1), sign(@as(T, -2))); |
| 1671 | 1669 | try std.testing.expectEqual(@as(T, 0), sign(@as(T, 0))); |
| 1672 | | // TODO - uncomment once @intToFloat supports vectors |
| 1673 | | // try std.testing.expectEqual(@Vector(3, T){ 1, -1, 0 }, sign(@Vector(3, T){ 2, -2, 0 })); |
| 1670 | try std.testing.expectEqual(@Vector(3, T){ 1, -1, 0 }, sign(@Vector(3, T){ 2, -2, 0 })); |
| 1674 | 1671 | } |
| 1675 | 1672 | { |
| 1676 | 1673 | const T = f32; |
| 1677 | 1674 | try std.testing.expectEqual(@as(T, 1), sign(@as(T, 2))); |
| 1678 | 1675 | try std.testing.expectEqual(@as(T, -1), sign(@as(T, -2))); |
| 1679 | 1676 | try std.testing.expectEqual(@as(T, 0), sign(@as(T, 0))); |
| 1680 | | // TODO - uncomment once @intToFloat supports vectors |
| 1681 | | // try std.testing.expectEqual(@Vector(3, T){ 1, -1, 0 }, sign(@Vector(3, T){ 2, -2, 0 })); |
| 1677 | try std.testing.expectEqual(@Vector(3, T){ 1, -1, 0 }, sign(@Vector(3, T){ 2, -2, 0 })); |
| 1682 | 1678 | } |
| 1683 | 1679 | { |
| 1684 | 1680 | const T = f64; |
| 1685 | 1681 | try std.testing.expectEqual(@as(T, 1), sign(@as(T, 2))); |
| 1686 | 1682 | try std.testing.expectEqual(@as(T, -1), sign(@as(T, -2))); |
| 1687 | 1683 | try std.testing.expectEqual(@as(T, 0), sign(@as(T, 0))); |
| 1688 | | // TODO - uncomment once @intToFloat supports vectors |
| 1689 | | // try std.testing.expectEqual(@Vector(3, T){ 1, -1, 0 }, sign(@Vector(3, T){ 2, -2, 0 })); |
| 1684 | try std.testing.expectEqual(@Vector(3, T){ 1, -1, 0 }, sign(@Vector(3, T){ 2, -2, 0 })); |
| 1690 | 1685 | } |
| 1691 | 1686 | |
| 1692 | 1687 | // comptime_int |