|
@@ -33,6 +33,8 @@ Type_Info_Simd_Vector :: runtime.Type_Info_Simd_Vector;
|
|
Type_Info_Relative_Pointer :: runtime.Type_Info_Relative_Pointer;
|
|
Type_Info_Relative_Pointer :: runtime.Type_Info_Relative_Pointer;
|
|
Type_Info_Relative_Slice :: runtime.Type_Info_Relative_Slice;
|
|
Type_Info_Relative_Slice :: runtime.Type_Info_Relative_Slice;
|
|
|
|
|
|
|
|
+Type_Info_Enum_Value :: runtime.Type_Info_Enum_Value;
|
|
|
|
+
|
|
|
|
|
|
Type_Kind :: enum {
|
|
Type_Kind :: enum {
|
|
Invalid,
|
|
Invalid,
|
|
@@ -111,7 +113,7 @@ backing_type_kind :: proc(T: typeid) -> Type_Kind {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-type_info_base :: proc(info: ^runtime.Type_Info) -> ^runtime.Type_Info {
|
|
|
|
|
|
+type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
|
|
if info == nil { return nil; }
|
|
if info == nil { return nil; }
|
|
|
|
|
|
base := info;
|
|
base := info;
|
|
@@ -125,7 +127,7 @@ type_info_base :: proc(info: ^runtime.Type_Info) -> ^runtime.Type_Info {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-type_info_core :: proc(info: ^runtime.Type_Info) -> ^runtime.Type_Info {
|
|
|
|
|
|
+type_info_core :: proc(info: ^Type_Info) -> ^Type_Info {
|
|
if info == nil { return nil; }
|
|
if info == nil { return nil; }
|
|
|
|
|
|
base := info;
|
|
base := info;
|
|
@@ -344,7 +346,7 @@ Struct_Tag :: distinct string;
|
|
|
|
|
|
Struct_Field :: struct {
|
|
Struct_Field :: struct {
|
|
name: string,
|
|
name: string,
|
|
- type: typeid,
|
|
|
|
|
|
+ type: ^Type_Info,
|
|
tag: Struct_Tag,
|
|
tag: Struct_Tag,
|
|
offset: uintptr,
|
|
offset: uintptr,
|
|
is_using: bool,
|
|
is_using: bool,
|
|
@@ -355,7 +357,7 @@ struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
|
|
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
|
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
|
if 0 <= i && i < len(s.names) {
|
|
if 0 <= i && i < len(s.names) {
|
|
field.name = s.names[i];
|
|
field.name = s.names[i];
|
|
- field.type = s.types[i].id;
|
|
|
|
|
|
+ field.type = s.types[i];
|
|
field.tag = Struct_Tag(s.tags[i]);
|
|
field.tag = Struct_Tag(s.tags[i]);
|
|
field.offset = s.offsets[i];
|
|
field.offset = s.offsets[i];
|
|
field.is_using = s.usings[i];
|
|
field.is_using = s.usings[i];
|
|
@@ -370,7 +372,7 @@ struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
|
|
for fname, i in s.names {
|
|
for fname, i in s.names {
|
|
if fname == name {
|
|
if fname == name {
|
|
field.name = s.names[i];
|
|
field.name = s.names[i];
|
|
- field.type = s.types[i].id;
|
|
|
|
|
|
+ field.type = s.types[i];
|
|
field.tag = Struct_Tag(s.tags[i]);
|
|
field.tag = Struct_Tag(s.tags[i]);
|
|
field.offset = s.offsets[i];
|
|
field.offset = s.offsets[i];
|
|
field.is_using = s.usings[i];
|
|
field.is_using = s.usings[i];
|
|
@@ -381,7 +383,7 @@ struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
-struct_field_value_by_name :: proc(a: any, field: string, recurse := false) -> any {
|
|
|
|
|
|
+struct_field_value_by_name :: proc(a: any, field: string, allow_using := false) -> any {
|
|
if a == nil { return nil; }
|
|
if a == nil { return nil; }
|
|
|
|
|
|
ti := runtime.type_info_base(type_info_of(a.id));
|
|
ti := runtime.type_info_base(type_info_of(a.id));
|
|
@@ -395,13 +397,13 @@ struct_field_value_by_name :: proc(a: any, field: string, recurse := false) -> a
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
- if recurse && s.usings[i] {
|
|
|
|
|
|
+ if allow_using && s.usings[i] {
|
|
f := any{
|
|
f := any{
|
|
rawptr(uintptr(a.data) + s.offsets[i]),
|
|
rawptr(uintptr(a.data) + s.offsets[i]),
|
|
s.types[i].id,
|
|
s.types[i].id,
|
|
};
|
|
};
|
|
|
|
|
|
- if res := struct_field_value_by_name(f, field, recurse); res != nil {
|
|
|
|
|
|
+ if res := struct_field_value_by_name(f, field, allow_using); res != nil {
|
|
return res;
|
|
return res;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -420,7 +422,7 @@ struct_field_names :: proc(T: typeid) -> []string {
|
|
return nil;
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
|
|
-struct_field_types :: proc(T: typeid) -> []^runtime.Type_Info {
|
|
|
|
|
|
+struct_field_types :: proc(T: typeid) -> []^Type_Info {
|
|
ti := runtime.type_info_base(type_info_of(T));
|
|
ti := runtime.type_info_base(type_info_of(T));
|
|
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
|
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
|
return s.types;
|
|
return s.types;
|
|
@@ -445,6 +447,20 @@ struct_field_offsets :: proc(T: typeid) -> []uintptr {
|
|
return nil;
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
|
|
|
|
+ ti := runtime.type_info_base(type_info_of(T));
|
|
|
|
+ if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
|
|
|
+ return soa_zip(
|
|
|
|
+ name = s.names,
|
|
|
|
+ type = s.types,
|
|
|
|
+ tag = transmute([]Struct_Tag)s.tags,
|
|
|
|
+ offset = s.offsets,
|
|
|
|
+ is_using = s.usings,
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ return nil;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
struct_tag_get :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag) {
|
|
struct_tag_get :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag) {
|
|
@@ -468,7 +484,7 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, o
|
|
switch t[i] {
|
|
switch t[i] {
|
|
case ':', '"':
|
|
case ':', '"':
|
|
break loop;
|
|
break loop;
|
|
- case 0x00 ..< ' ', 0x7f .. 0x9f: // break if control character is found
|
|
|
|
|
|
+ case 0x00 ..< ' ', 0x7f ..= 0x9f: // break if control character is found
|
|
break loop;
|
|
break loop;
|
|
}
|
|
}
|
|
i += 1;
|
|
i += 1;
|
|
@@ -516,7 +532,7 @@ enum_string :: proc(a: any) -> string {
|
|
if e, ok := ti.variant.(runtime.Type_Info_Enum); ok {
|
|
if e, ok := ti.variant.(runtime.Type_Info_Enum); ok {
|
|
v, _ := as_i64(a);
|
|
v, _ := as_i64(a);
|
|
for value, i in e.values {
|
|
for value, i in e.values {
|
|
- if value == runtime.Type_Info_Enum_Value(v) {
|
|
|
|
|
|
+ if value == Type_Info_Enum_Value(v) {
|
|
return e.names[i];
|
|
return e.names[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -528,26 +544,24 @@ enum_string :: proc(a: any) -> string {
|
|
}
|
|
}
|
|
|
|
|
|
// Given a enum type and a value name, get the enum value.
|
|
// Given a enum type and a value name, get the enum value.
|
|
-enum_from_name :: proc($EnumType: typeid, name: string) -> (value: EnumType, ok: bool) {
|
|
|
|
- ti := type_info_base(type_info_of(EnumType));
|
|
|
|
|
|
+enum_from_name :: proc($Enum_Type: typeid, name: string) -> (value: Enum_Type, ok: bool) {
|
|
|
|
+ ti := type_info_base(type_info_of(Enum_Type));
|
|
if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
|
if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
|
for value_name, i in eti.names {
|
|
for value_name, i in eti.names {
|
|
if value_name != name {
|
|
if value_name != name {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
v := eti.values[i];
|
|
v := eti.values[i];
|
|
- value = EnumType(v);
|
|
|
|
|
|
+ value = Enum_Type(v);
|
|
ok = true;
|
|
ok = true;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- panic("expected enum type to reflect.enum_from_name");
|
|
|
|
}
|
|
}
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
-enum_from_name_any :: proc(EnumType: typeid, name: string) -> (value: runtime.Type_Info_Enum_Value, ok: bool) {
|
|
|
|
- ti := runtime.type_info_base(type_info_of(EnumType));
|
|
|
|
|
|
+enum_from_name_any :: proc(Enum_Type: typeid, name: string) -> (value: Type_Info_Enum_Value, ok: bool) {
|
|
|
|
+ ti := runtime.type_info_base(type_info_of(Enum_Type));
|
|
if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
|
if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
|
for value_name, i in eti.names {
|
|
for value_name, i in eti.names {
|
|
if value_name != name {
|
|
if value_name != name {
|
|
@@ -557,14 +571,42 @@ enum_from_name_any :: proc(EnumType: typeid, name: string) -> (value: runtime.Ty
|
|
ok = true;
|
|
ok = true;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- panic("expected enum type to reflect.enum_from_name_any");
|
|
|
|
}
|
|
}
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-union_variant_type_info :: proc(a: any) -> ^runtime.Type_Info {
|
|
|
|
|
|
+enum_field_names :: proc(Enum_Type: typeid) -> []string {
|
|
|
|
+ ti := runtime.type_info_base(type_info_of(Enum_Type));
|
|
|
|
+ if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
|
|
|
+ return eti.names;
|
|
|
|
+ }
|
|
|
|
+ return nil;
|
|
|
|
+}
|
|
|
|
+enum_field_values :: proc(Enum_Type: typeid) -> []Type_Info_Enum_Value {
|
|
|
|
+ ti := runtime.type_info_base(type_info_of(Enum_Type));
|
|
|
|
+ if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
|
|
|
+ return eti.values;
|
|
|
|
+ }
|
|
|
|
+ return nil;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+Enum_Field :: struct {
|
|
|
|
+ name: string,
|
|
|
|
+ value: Type_Info_Enum_Value,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+enum_fields_zipped :: proc(Enum_Type: typeid) -> (fields: #soa[]Enum_Field) {
|
|
|
|
+ ti := runtime.type_info_base(type_info_of(Enum_Type));
|
|
|
|
+ if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
|
|
|
+ return soa_zip(name=eti.names, value=eti.values);
|
|
|
|
+ }
|
|
|
|
+ return nil;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+union_variant_type_info :: proc(a: any) -> ^Type_Info {
|
|
id := union_variant_typeid(a);
|
|
id := union_variant_typeid(a);
|
|
return type_info_of(id);
|
|
return type_info_of(id);
|
|
}
|
|
}
|