| ... | @@ -72,6 +72,17 @@ pub const Type = extern union { | ... | @@ -72,6 +72,17 @@ pub const Type = extern union { |
| 72 | } | 72 | } |
| 73 | } | 73 | } |
| 74 | | 74 | |
| | 75 | pub fn cast(self: Type, comptime T: type) ?*T { |
| | 76 | if (self.tag_if_small_enough < Tag.no_payload_count) |
| | 77 | return null; |
| | 78 | |
| | 79 | const expected_tag = std.meta.fieldInfo(T, "base").default_value.?.tag; |
| | 80 | if (self.ptr_otherwise.tag != expected_tag) |
| | 81 | return null; |
| | 82 | |
| | 83 | return @fieldParentPtr(T, "base", self.ptr_otherwise); |
| | 84 | } |
| | 85 | |
| 75 | pub fn format( | 86 | pub fn format( |
| 76 | self: Type, | 87 | self: Type, |
| 77 | comptime fmt: []const u8, | 88 | comptime fmt: []const u8, |
| ... | @@ -133,6 +144,150 @@ pub const Type = extern union { | ... | @@ -133,6 +144,150 @@ pub const Type = extern union { |
| 133 | } | 144 | } |
| 134 | } | 145 | } |
| 135 | | 146 | |
| | 147 | pub fn isSinglePointer(self: Type) bool { |
| | 148 | return switch (self.tag()) { |
| | 149 | .@"u8", |
| | 150 | .@"i8", |
| | 151 | .@"isize", |
| | 152 | .@"usize", |
| | 153 | .@"c_short", |
| | 154 | .@"c_ushort", |
| | 155 | .@"c_int", |
| | 156 | .@"c_uint", |
| | 157 | .@"c_long", |
| | 158 | .@"c_ulong", |
| | 159 | .@"c_longlong", |
| | 160 | .@"c_ulonglong", |
| | 161 | .@"c_longdouble", |
| | 162 | .@"f16", |
| | 163 | .@"f32", |
| | 164 | .@"f64", |
| | 165 | .@"f128", |
| | 166 | .@"c_void", |
| | 167 | .@"bool", |
| | 168 | .@"void", |
| | 169 | .@"type", |
| | 170 | .@"anyerror", |
| | 171 | .@"comptime_int", |
| | 172 | .@"comptime_float", |
| | 173 | .@"noreturn", |
| | 174 | .array, |
| | 175 | .array_u8_sentinel_0, |
| | 176 | .const_slice_u8, |
| | 177 | => false, |
| | 178 | |
| | 179 | .single_const_pointer => true, |
| | 180 | }; |
| | 181 | } |
| | 182 | |
| | 183 | pub fn isSlice(self: Type) bool { |
| | 184 | return switch (self.tag()) { |
| | 185 | .@"u8", |
| | 186 | .@"i8", |
| | 187 | .@"isize", |
| | 188 | .@"usize", |
| | 189 | .@"c_short", |
| | 190 | .@"c_ushort", |
| | 191 | .@"c_int", |
| | 192 | .@"c_uint", |
| | 193 | .@"c_long", |
| | 194 | .@"c_ulong", |
| | 195 | .@"c_longlong", |
| | 196 | .@"c_ulonglong", |
| | 197 | .@"c_longdouble", |
| | 198 | .@"f16", |
| | 199 | .@"f32", |
| | 200 | .@"f64", |
| | 201 | .@"f128", |
| | 202 | .@"c_void", |
| | 203 | .@"bool", |
| | 204 | .@"void", |
| | 205 | .@"type", |
| | 206 | .@"anyerror", |
| | 207 | .@"comptime_int", |
| | 208 | .@"comptime_float", |
| | 209 | .@"noreturn", |
| | 210 | .array, |
| | 211 | .array_u8_sentinel_0, |
| | 212 | .single_const_pointer, |
| | 213 | => false, |
| | 214 | |
| | 215 | .const_slice_u8 => true, |
| | 216 | }; |
| | 217 | } |
| | 218 | |
| | 219 | /// Asserts the type is a pointer type. |
| | 220 | pub fn pointerIsConst(self: Type) bool { |
| | 221 | return switch (self.tag()) { |
| | 222 | .@"u8", |
| | 223 | .@"i8", |
| | 224 | .@"isize", |
| | 225 | .@"usize", |
| | 226 | .@"c_short", |
| | 227 | .@"c_ushort", |
| | 228 | .@"c_int", |
| | 229 | .@"c_uint", |
| | 230 | .@"c_long", |
| | 231 | .@"c_ulong", |
| | 232 | .@"c_longlong", |
| | 233 | .@"c_ulonglong", |
| | 234 | .@"c_longdouble", |
| | 235 | .@"f16", |
| | 236 | .@"f32", |
| | 237 | .@"f64", |
| | 238 | .@"f128", |
| | 239 | .@"c_void", |
| | 240 | .@"bool", |
| | 241 | .@"void", |
| | 242 | .@"type", |
| | 243 | .@"anyerror", |
| | 244 | .@"comptime_int", |
| | 245 | .@"comptime_float", |
| | 246 | .@"noreturn", |
| | 247 | .array, |
| | 248 | .array_u8_sentinel_0, |
| | 249 | => unreachable, |
| | 250 | |
| | 251 | .single_const_pointer, .const_slice_u8 => true, |
| | 252 | }; |
| | 253 | } |
| | 254 | |
| | 255 | /// Asserts the type is a pointer or array type. |
| | 256 | pub fn elemType(self: Type) Type { |
| | 257 | return switch (self.tag()) { |
| | 258 | .@"u8", |
| | 259 | .@"i8", |
| | 260 | .@"isize", |
| | 261 | .@"usize", |
| | 262 | .@"c_short", |
| | 263 | .@"c_ushort", |
| | 264 | .@"c_int", |
| | 265 | .@"c_uint", |
| | 266 | .@"c_long", |
| | 267 | .@"c_ulong", |
| | 268 | .@"c_longlong", |
| | 269 | .@"c_ulonglong", |
| | 270 | .@"c_longdouble", |
| | 271 | .@"f16", |
| | 272 | .@"f32", |
| | 273 | .@"f64", |
| | 274 | .@"f128", |
| | 275 | .@"c_void", |
| | 276 | .@"bool", |
| | 277 | .@"void", |
| | 278 | .@"type", |
| | 279 | .@"anyerror", |
| | 280 | .@"comptime_int", |
| | 281 | .@"comptime_float", |
| | 282 | .@"noreturn", |
| | 283 | => unreachable, |
| | 284 | |
| | 285 | .array => self.cast(Payload.Array).?.elem_type, |
| | 286 | .single_const_pointer => self.cast(Payload.SingleConstPointer).?.pointee_type, |
| | 287 | .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.@"u8"), |
| | 288 | }; |
| | 289 | } |
| | 290 | |
| 136 | /// This enum does not directly correspond to `std.builtin.TypeId` because | 291 | /// This enum does not directly correspond to `std.builtin.TypeId` because |
| 137 | /// it has extra enum tags in it, as a way of using less memory. For example, | 292 | /// it has extra enum tags in it, as a way of using less memory. For example, |
| 138 | /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types | 293 | /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types |