| ... | @@ -890,38 +890,10 @@ pub fn cast(comptime DestType: type, target: anytype) DestType { | ... | @@ -890,38 +890,10 @@ pub fn cast(comptime DestType: type, target: anytype) DestType { |
| 890 | // this function should behave like transCCast in translate-c, except it's for macros and enums | 890 | // this function should behave like transCCast in translate-c, except it's for macros and enums |
| 891 | const SourceType = @TypeOf(target); | 891 | const SourceType = @TypeOf(target); |
| 892 | switch (@typeInfo(DestType)) { | 892 | switch (@typeInfo(DestType)) { |
| 893 | .Pointer => { | 893 | .Pointer => return castToPtr(DestType, SourceType, target), |
| 894 | switch (@typeInfo(SourceType)) { | | |
| 895 | .Int, .ComptimeInt => { | | |
| 896 | return @intToPtr(DestType, target); | | |
| 897 | }, | | |
| 898 | .Pointer => { | | |
| 899 | return castPtr(DestType, target); | | |
| 900 | }, | | |
| 901 | .Optional => |opt| { | | |
| 902 | if (@typeInfo(opt.child) == .Pointer) { | | |
| 903 | return castPtr(DestType, target); | | |
| 904 | } | | |
| 905 | }, | | |
| 906 | else => {}, | | |
| 907 | } | | |
| 908 | }, | | |
| 909 | .Optional => |dest_opt| { | 894 | .Optional => |dest_opt| { |
| 910 | if (@typeInfo(dest_opt.child) == .Pointer) { | 895 | if (@typeInfo(dest_opt.child) == .Pointer) { |
| 911 | switch (@typeInfo(SourceType)) { | 896 | return castToPtr(DestType, SourceType, target); |
| 912 | .Int, .ComptimeInt => { | | |
| 913 | return @intToPtr(DestType, target); | | |
| 914 | }, | | |
| 915 | .Pointer => { | | |
| 916 | return castPtr(DestType, target); | | |
| 917 | }, | | |
| 918 | .Optional => |target_opt| { | | |
| 919 | if (@typeInfo(target_opt.child) == .Pointer) { | | |
| 920 | return castPtr(DestType, target); | | |
| 921 | } | | |
| 922 | }, | | |
| 923 | else => {}, | | |
| 924 | } | | |
| 925 | } | 897 | } |
| 926 | }, | 898 | }, |
| 927 | .Enum => |enum_type| { | 899 | .Enum => |enum_type| { |
| ... | @@ -977,6 +949,30 @@ fn castPtr(comptime DestType: type, target: anytype) DestType { | ... | @@ -977,6 +949,30 @@ fn castPtr(comptime DestType: type, target: anytype) DestType { |
| 977 | return @ptrCast(DestType, @alignCast(dest.alignment, target)); | 949 | return @ptrCast(DestType, @alignCast(dest.alignment, target)); |
| 978 | } | 950 | } |
| 979 | | 951 | |
| | 952 | fn castToPtr(comptime DestType: type, comptime SourceType: type, target: anytype) DestType { |
| | 953 | switch (@typeInfo(SourceType)) { |
| | 954 | .Int => { |
| | 955 | return @intToPtr(DestType, castInt(usize, target)); |
| | 956 | }, |
| | 957 | .ComptimeInt => { |
| | 958 | if (target < 0) |
| | 959 | return @intToPtr(DestType, @bitCast(usize, @intCast(isize, target))) |
| | 960 | else |
| | 961 | return @intToPtr(DestType, @intCast(usize, target)); |
| | 962 | }, |
| | 963 | .Pointer => { |
| | 964 | return castPtr(DestType, target); |
| | 965 | }, |
| | 966 | .Optional => |target_opt| { |
| | 967 | if (@typeInfo(target_opt.child) == .Pointer) { |
| | 968 | return castPtr(DestType, target); |
| | 969 | } |
| | 970 | }, |
| | 971 | else => {}, |
| | 972 | } |
| | 973 | return @as(DestType, target); |
| | 974 | } |
| | 975 | |
| 980 | fn ptrInfo(comptime PtrType: type) TypeInfo.Pointer { | 976 | fn ptrInfo(comptime PtrType: type) TypeInfo.Pointer { |
| 981 | return switch (@typeInfo(PtrType)) { | 977 | return switch (@typeInfo(PtrType)) { |
| 982 | .Optional => |opt_info| @typeInfo(opt_info.child).Pointer, | 978 | .Optional => |opt_info| @typeInfo(opt_info.child).Pointer, |
| ... | @@ -1026,6 +1022,12 @@ test "std.meta.cast" { | ... | @@ -1026,6 +1022,12 @@ test "std.meta.cast" { |
| 1026 | try testing.expectEqual(cast(C_ENUM, @as(i8, 1)), .B); | 1022 | try testing.expectEqual(cast(C_ENUM, @as(i8, 1)), .B); |
| 1027 | try testing.expectEqual(cast(C_ENUM, @as(u64, 1)), .B); | 1023 | try testing.expectEqual(cast(C_ENUM, @as(u64, 1)), .B); |
| 1028 | try testing.expectEqual(cast(C_ENUM, @as(u64, 42)), @intToEnum(C_ENUM, 42)); | 1024 | try testing.expectEqual(cast(C_ENUM, @as(u64, 42)), @intToEnum(C_ENUM, 42)); |
| | 1025 | |
| | 1026 | var foo: c_int = -1; |
| | 1027 | try testing.expect(cast(*c_void, -1) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)))); |
| | 1028 | try testing.expect(cast(*c_void, foo) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)))); |
| | 1029 | try testing.expect(cast(?*c_void, -1) == @intToPtr(?*c_void, @bitCast(usize, @as(isize, -1)))); |
| | 1030 | try testing.expect(cast(?*c_void, foo) == @intToPtr(?*c_void, @bitCast(usize, @as(isize, -1)))); |
| 1029 | } | 1031 | } |
| 1030 | | 1032 | |
| 1031 | /// Given a value returns its size as C's sizeof operator would. | 1033 | /// Given a value returns its size as C's sizeof operator would. |