mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Update package reflect
This commit is contained in:
+52
-28
@@ -344,24 +344,29 @@ index :: proc(val: any, i: int, loc := #caller_location) -> any {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Struct_Tag represents the type of the string of a struct field
|
||||||
|
//
|
||||||
|
// Through convention, tags are the concatenation of optionally space separationed key:"value" pairs.
|
||||||
|
// Each key is a non-empty string which contains no control characters other than space, quotes, and colon.
|
||||||
Struct_Tag :: distinct string;
|
Struct_Tag :: distinct string;
|
||||||
|
|
||||||
Struct_Field :: struct {
|
Struct_Field :: struct {
|
||||||
name: string,
|
name: string,
|
||||||
type: typeid,
|
type: typeid,
|
||||||
tag: Struct_Tag,
|
tag: Struct_Tag,
|
||||||
offset: uintptr,
|
offset: uintptr,
|
||||||
|
is_using: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
|
struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
|
||||||
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 {
|
||||||
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].id;
|
||||||
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -372,10 +377,11 @@ struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
|
|||||||
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
||||||
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].id;
|
||||||
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];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,23 +537,41 @@ 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) {
|
enum_from_name :: proc($EnumType: typeid, name: string) -> (value: EnumType, ok: bool) {
|
||||||
ti := type_info_base(type_info_of(EnumType));
|
ti := type_info_base(type_info_of(EnumType));
|
||||||
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 = EnumType(v);
|
||||||
ok = true;
|
ok = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic("expected enum type to reflect.enum_from_name");
|
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));
|
||||||
|
if eti, eti_ok := ti.variant.(runtime.Type_Info_Enum); eti_ok {
|
||||||
|
for value_name, i in eti.names {
|
||||||
|
if value_name != name {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
value = eti.values[i];
|
||||||
|
ok = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic("expected enum type to reflect.enum_from_name_any");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
union_variant_type_info :: proc(a: any) -> ^runtime.Type_Info {
|
union_variant_type_info :: proc(a: any) -> ^runtime.Type_Info {
|
||||||
id := union_variant_typeid(a);
|
id := union_variant_typeid(a);
|
||||||
return type_info_of(id);
|
return type_info_of(id);
|
||||||
|
|||||||
+11
-1
@@ -108,7 +108,6 @@ duration_truncate :: proc(d, m: Duration) -> Duration {
|
|||||||
return d if m <= 0 else d - d%m;
|
return d if m <= 0 else d - d%m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
date :: proc(t: Time) -> (year: int, month: Month, day: int) {
|
date :: proc(t: Time) -> (year: int, month: Month, day: int) {
|
||||||
year, month, day, _ = _abs_date(_time_abs(t), true);
|
year, month, day, _ = _abs_date(_time_abs(t), true);
|
||||||
return;
|
return;
|
||||||
@@ -160,6 +159,17 @@ unix :: proc(sec: i64, nsec: i64) -> Time {
|
|||||||
return Time{(sec*1e9 + nsec) + UNIX_TO_INTERNAL};
|
return Time{(sec*1e9 + nsec) + UNIX_TO_INTERNAL};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_to_unix :: proc(t: Time) -> i64 {
|
||||||
|
return t._nsec/1e9;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_to_unix_nano :: proc(t: Time) -> i64 {
|
||||||
|
return t._nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_add :: proc(t: Time, d: Duration) -> Time {
|
||||||
|
return Time{t._nsec + i64(d)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ABSOLUTE_ZERO_YEAR :: i64(-292277022399); // Day is chosen so that 2001-01-01 is Monday in the calculations
|
ABSOLUTE_ZERO_YEAR :: i64(-292277022399); // Day is chosen so that 2001-01-01 is Monday in the calculations
|
||||||
|
|||||||
Reference in New Issue
Block a user