jc/meta/type_info.jai
2025-05-25 15:10:06 -06:00

80 lines
1.8 KiB
Text

// These return the bool first so you can check in a conditional,
// rather than having to do '_, ok := ...'
check_type_tag :: ($$T: Type, tag: Type_Info_Tag) -> bool, *Type_Info {
#if is_constant(T) {
info :: type_info(T);
if info.type == tag return true, info;
}
else {
info := T.(*Type_Info);
if info.type == tag return true, info;
}
return false, null;
}
type_is_integer :: ($$T: Type) -> bool, *Type_Info_Integer {
ok, info := check_type_tag(T, .INTEGER);
return ok, info.(*Type_Info_Integer);
}
type_is_float :: ($$T: Type) -> bool, *Type_Info_Float {
ok, info := check_type_tag(T, .FLOAT);
return ok, info.(*Type_Info_Float);
}
type_is_scalar :: (t: Type) -> bool {
return type_is_integer(t) || type_is_float(t);
}
type_is_array :: ($$T: Type) -> bool, *Type_Info_Array {
ok, info := check_type_tag(T, .ARRAY);
return ok, info.(*Type_Info_Array);
}
type_is_struct :: ($$T: Type) -> bool, *Type_Info_Struct {
ok, info := check_type_tag(T, .STRUCT);
return ok, info.(*Type_Info_Struct);
}
type_is_enum :: ($$T: Type) -> bool, *Type_Info_Enum {
ok, info := check_type_tag(T, .ENUM);
return ok, info.(*Type_Info_Enum);
}
enum_min :: (T: Type) -> int #expand {
return #run -> int {
ok, info := type_is_enum(T);
assert(ok, "type given to enum_min must be an enum");
if info.values.count == 0 {
return 0;
}
min := 0xFFFFFF_FFFFFF;
for info.values if it < min {
min = it;
}
return min;
};
}
enum_max :: (T: Type) -> int #expand {
return #run -> int {
ok, info := type_is_enum(T);
assert(ok, "type given to enum_max must be an enum");
if info.values.count == 0 {
return 0;
}
max := 0;
for info.values if it > max {
max = it;
}
return max;
};
}