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