| ... | ... | @@ -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 | 86 | pub fn format( |
| 76 | 87 | self: Type, |
| 77 | 88 | comptime fmt: []const u8, |
| ... | ... | @@ -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 | 291 | /// This enum does not directly correspond to `std.builtin.TypeId` because |
| 137 | 292 | /// it has extra enum tags in it, as a way of using less memory. For example, |
| 138 | 293 | /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types |