Add @(require_results) to package reflect

This commit is contained in:
gingerBill
2023-01-29 11:28:05 +00:00
parent c45ca1bfcc
commit 8d43cc840a
3 changed files with 86 additions and 3 deletions

View File

@@ -2,6 +2,7 @@ package reflect
import "core:runtime"
@(require_results)
iterate_array :: proc(val: any, it: ^int) -> (elem: any, index: int, ok: bool) {
if val == nil || it == nil {
return
@@ -41,6 +42,7 @@ iterate_array :: proc(val: any, it: ^int) -> (elem: any, index: int, ok: bool) {
return
}
@(require_results)
iterate_map :: proc(val: any, it: ^int) -> (key, value: any, ok: bool) {
if val == nil || it == nil {
return

View File

@@ -74,6 +74,7 @@ Type_Kind :: enum {
}
@(require_results)
type_kind :: proc(T: typeid) -> Type_Kind {
ti := type_info_of(T)
if ti != nil {
@@ -113,11 +114,13 @@ type_kind :: proc(T: typeid) -> Type_Kind {
}
// TODO(bill): Better name
@(require_results)
underlying_type_kind :: proc(T: typeid) -> Type_Kind {
return type_kind(runtime.typeid_base(T))
}
// TODO(bill): Better name
@(require_results)
backing_type_kind :: proc(T: typeid) -> Type_Kind {
return type_kind(runtime.typeid_core(T))
}
@@ -135,6 +138,7 @@ when !ODIN_DISALLOW_RTTI {
}
@(require_results)
any_base :: proc(v: any) -> any {
v := v
if v != nil {
@@ -142,6 +146,7 @@ any_base :: proc(v: any) -> any {
}
return v
}
@(require_results)
any_core :: proc(v: any) -> any {
v := v
if v != nil {
@@ -150,6 +155,7 @@ any_core :: proc(v: any) -> any {
return v
}
@(require_results)
typeid_elem :: proc(id: typeid) -> typeid {
ti := type_info_of(id)
if ti == nil { return nil }
@@ -179,6 +185,7 @@ typeid_elem :: proc(id: typeid) -> typeid {
}
@(require_results)
size_of_typeid :: proc(T: typeid) -> int {
if ti := type_info_of(T); ti != nil {
return ti.size
@@ -186,6 +193,7 @@ size_of_typeid :: proc(T: typeid) -> int {
return 0
}
@(require_results)
align_of_typeid :: proc(T: typeid) -> int {
if ti := type_info_of(T); ti != nil {
return ti.align
@@ -193,6 +201,7 @@ align_of_typeid :: proc(T: typeid) -> int {
return 1
}
@(require_results)
as_bytes :: proc(v: any) -> []byte {
if v != nil {
sz := size_of_typeid(v.id)
@@ -201,10 +210,12 @@ as_bytes :: proc(v: any) -> []byte {
return nil
}
@(require_results)
any_data :: #force_inline proc(v: any) -> (data: rawptr, id: typeid) {
return v.data, v.id
}
@(require_results)
is_nil :: proc(v: any) -> bool {
if v == nil {
return true
@@ -221,6 +232,7 @@ is_nil :: proc(v: any) -> bool {
return true
}
@(require_results)
length :: proc(val: any) -> int {
if val == nil { return 0 }
@@ -256,6 +268,7 @@ length :: proc(val: any) -> int {
return 0
}
@(require_results)
capacity :: proc(val: any) -> int {
if val == nil { return 0 }
@@ -282,6 +295,7 @@ capacity :: proc(val: any) -> int {
}
@(require_results)
index :: proc(val: any, i: int, loc := #caller_location) -> any {
if val == nil { return nil }
@@ -341,6 +355,7 @@ index :: proc(val: any, i: int, loc := #caller_location) -> any {
return nil
}
@(require_results)
deref :: proc(val: any) -> any {
if val != nil {
ti := type_info_base(type_info_of(val.id))
@@ -370,6 +385,7 @@ Struct_Field :: struct {
is_using: bool,
}
@(require_results)
struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
@@ -384,6 +400,7 @@ struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
return
}
@(require_results)
struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
@@ -401,6 +418,7 @@ struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
return
}
@(require_results)
struct_field_value_by_name :: proc(a: any, field: string, allow_using := false) -> any {
if a == nil { return nil }
@@ -432,6 +450,7 @@ struct_field_value_by_name :: proc(a: any, field: string, allow_using := false)
@(require_results)
struct_field_names :: proc(T: typeid) -> []string {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
@@ -440,6 +459,7 @@ struct_field_names :: proc(T: typeid) -> []string {
return nil
}
@(require_results)
struct_field_types :: proc(T: typeid) -> []^Type_Info {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
@@ -449,6 +469,7 @@ struct_field_types :: proc(T: typeid) -> []^Type_Info {
}
@(require_results)
struct_field_tags :: proc(T: typeid) -> []Struct_Tag {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
@@ -457,6 +478,7 @@ struct_field_tags :: proc(T: typeid) -> []Struct_Tag {
return nil
}
@(require_results)
struct_field_offsets :: proc(T: typeid) -> []uintptr {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
@@ -465,6 +487,7 @@ struct_field_offsets :: proc(T: typeid) -> []uintptr {
return nil
}
@(require_results)
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 {
@@ -481,11 +504,13 @@ struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
@(require_results)
struct_tag_get :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag) {
value, _ = struct_tag_lookup(tag, key)
return
}
@(require_results)
struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, ok: bool) {
for t := tag; t != ""; /**/ {
i := 0
@@ -544,6 +569,7 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: Struct_Tag, o
}
@(require_results)
enum_string :: proc(a: any) -> string {
if a == nil { return "" }
ti := runtime.type_info_base(type_info_of(a.id))
@@ -562,6 +588,7 @@ enum_string :: proc(a: any) -> string {
}
// Given a enum type and a value name, get the enum value.
@(require_results)
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 {
@@ -578,6 +605,7 @@ enum_from_name :: proc($Enum_Type: typeid, name: string) -> (value: Enum_Type, o
return
}
@(require_results)
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 {
@@ -594,6 +622,7 @@ enum_from_name_any :: proc(Enum_Type: typeid, name: string) -> (value: Type_Info
}
@(require_results)
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 {
@@ -601,6 +630,7 @@ enum_field_names :: proc(Enum_Type: typeid) -> []string {
}
return nil
}
@(require_results)
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 {
@@ -614,6 +644,7 @@ Enum_Field :: struct {
value: Type_Info_Enum_Value,
}
@(require_results)
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 {
@@ -624,15 +655,18 @@ enum_fields_zipped :: proc(Enum_Type: typeid) -> (fields: #soa[]Enum_Field) {
@(require_results)
union_variant_type_info :: proc(a: any) -> ^Type_Info {
id := union_variant_typeid(a)
return type_info_of(id)
}
@(require_results)
type_info_union_is_pure_maybe :: proc(info: runtime.Type_Info_Union) -> bool {
return len(info.variants) == 1 && is_pointer(info.variants[0])
}
@(require_results)
union_variant_typeid :: proc(a: any) -> typeid {
if a == nil { return nil }
@@ -672,6 +706,7 @@ union_variant_typeid :: proc(a: any) -> typeid {
panic("expected a union to reflect.union_variant_typeid")
}
@(require_results)
get_union_variant_raw_tag :: proc(a: any) -> i64 {
if a == nil { return -1 }
@@ -702,6 +737,7 @@ get_union_variant_raw_tag :: proc(a: any) -> i64 {
panic("expected a union to reflect.get_union_variant_raw_tag")
}
@(require_results)
get_union_variant :: proc(a: any) -> any {
if a == nil {
return nil
@@ -713,6 +749,7 @@ get_union_variant :: proc(a: any) -> any {
return any{a.data, id}
}
@(require_results)
get_union_as_ptr_variants :: proc(val: ^$T) -> (res: intrinsics.type_convert_variants_to_pointers(T)) where intrinsics.type_is_union(T) {
ptr := rawptr(val)
tag := get_union_variant_raw_tag(val^)
@@ -813,6 +850,7 @@ set_union_variant_type_info :: proc(a: any, tag_ti: ^Type_Info) {
panic("expected a union to reflect.set_union_variant_type_info")
}
@(require_results)
set_union_value :: proc(dst: any, value: any) -> bool {
if dst == nil { return false }
@@ -853,6 +891,7 @@ set_union_value :: proc(dst: any, value: any) -> bool {
@(require_results)
as_bool :: proc(a: any) -> (value: bool, valid: bool) {
if a == nil { return }
a := a
@@ -875,6 +914,7 @@ as_bool :: proc(a: any) -> (value: bool, valid: bool) {
return
}
@(require_results)
as_int :: proc(a: any) -> (value: int, valid: bool) {
v: i64
v, valid = as_i64(a)
@@ -882,6 +922,7 @@ as_int :: proc(a: any) -> (value: int, valid: bool) {
return
}
@(require_results)
as_uint :: proc(a: any) -> (value: uint, valid: bool) {
v: u64
v, valid = as_u64(a)
@@ -889,6 +930,7 @@ as_uint :: proc(a: any) -> (value: uint, valid: bool) {
return
}
@(require_results)
as_i64 :: proc(a: any) -> (value: i64, valid: bool) {
if a == nil { return }
a := a
@@ -996,6 +1038,7 @@ as_i64 :: proc(a: any) -> (value: i64, valid: bool) {
return
}
@(require_results)
as_u64 :: proc(a: any) -> (value: u64, valid: bool) {
if a == nil { return }
a := a
@@ -1105,6 +1148,7 @@ as_u64 :: proc(a: any) -> (value: u64, valid: bool) {
}
@(require_results)
as_f64 :: proc(a: any) -> (value: f64, valid: bool) {
if a == nil { return }
a := a
@@ -1211,6 +1255,7 @@ as_f64 :: proc(a: any) -> (value: f64, valid: bool) {
}
@(require_results)
as_string :: proc(a: any) -> (value: string, valid: bool) {
if a == nil { return }
a := a
@@ -1230,6 +1275,7 @@ as_string :: proc(a: any) -> (value: string, valid: bool) {
return
}
@(require_results)
relative_pointer_to_absolute :: proc(a: any) -> rawptr {
if a == nil { return nil }
a := a
@@ -1244,6 +1290,7 @@ relative_pointer_to_absolute :: proc(a: any) -> rawptr {
}
@(require_results)
relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid) -> rawptr {
_handle :: proc(ptr: ^$T) -> rawptr where intrinsics.type_is_integer(T) {
if ptr^ == 0 {
@@ -1286,6 +1333,7 @@ relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid)
@(require_results)
as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) {
if a == nil { return }
a := a
@@ -1313,6 +1361,7 @@ as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) {
}
@(require_results)
as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) {
if a == nil { return }
a := a
@@ -1349,9 +1398,11 @@ ne :: not_equal
DEFAULT_EQUAL_MAX_RECURSION_LEVEL :: 32
@(require_results)
not_equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool {
return !equal(a, b, including_indirect_array_recursion, recursion_level)
}
@(require_results)
equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool {
if a == nil && b == nil {
return true

View File

@@ -3,17 +3,16 @@ package reflect
import "core:io"
import "core:strings"
@(require_results)
are_types_identical :: proc(a, b: ^Type_Info) -> bool {
if a == b {
return true
}
if (a == nil && b != nil) ||
(a != nil && b == nil) {
if a == nil || b == nil {
return false
}
switch {
case a.size != b.size, a.align != b.align:
return false
@@ -180,6 +179,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
return false
}
@(require_results)
is_signed :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
#partial switch i in type_info_base(info).variant {
@@ -188,6 +188,7 @@ is_signed :: proc(info: ^Type_Info) -> bool {
}
return false
}
@(require_results)
is_unsigned :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
#partial switch i in type_info_base(info).variant {
@@ -197,6 +198,7 @@ is_unsigned :: proc(info: ^Type_Info) -> bool {
return false
}
@(require_results)
is_byte :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
#partial switch i in type_info_base(info).variant {
@@ -206,66 +208,79 @@ is_byte :: proc(info: ^Type_Info) -> bool {
}
@(require_results)
is_integer :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Integer)
return ok
}
@(require_results)
is_rune :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Rune)
return ok
}
@(require_results)
is_float :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Float)
return ok
}
@(require_results)
is_complex :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Complex)
return ok
}
@(require_results)
is_quaternion :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Quaternion)
return ok
}
@(require_results)
is_any :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Any)
return ok
}
@(require_results)
is_string :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_String)
return ok
}
@(require_results)
is_cstring :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
v, ok := type_info_base(info).variant.(Type_Info_String)
return ok && v.is_cstring
}
@(require_results)
is_boolean :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Boolean)
return ok
}
@(require_results)
is_pointer :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Pointer)
return ok
}
@(require_results)
is_multi_pointer :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Multi_Pointer)
return ok
}
@(require_results)
is_soa_pointer :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Soa_Pointer)
return ok
}
@(require_results)
is_pointer_internally :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
#partial switch v in info.variant {
@@ -277,76 +292,91 @@ is_pointer_internally :: proc(info: ^Type_Info) -> bool {
}
return false
}
@(require_results)
is_procedure :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Procedure)
return ok
}
@(require_results)
is_array :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Array)
return ok
}
@(require_results)
is_enumerated_array :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Enumerated_Array)
return ok
}
@(require_results)
is_dynamic_array :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Dynamic_Array)
return ok
}
@(require_results)
is_dynamic_map :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Map)
return ok
}
@(require_results)
is_bit_set :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Bit_Set)
return ok
}
@(require_results)
is_slice :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Slice)
return ok
}
@(require_results)
is_tuple :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Tuple)
return ok
}
@(require_results)
is_struct :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
s, ok := type_info_base(info).variant.(Type_Info_Struct)
return ok && !s.is_raw_union
}
@(require_results)
is_raw_union :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
s, ok := type_info_base(info).variant.(Type_Info_Struct)
return ok && s.is_raw_union
}
@(require_results)
is_union :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Union)
return ok
}
@(require_results)
is_enum :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Enum)
return ok
}
@(require_results)
is_simd_vector :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Simd_Vector)
return ok
}
@(require_results)
is_relative_pointer :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Relative_Pointer)
return ok
}
@(require_results)
is_relative_slice :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
_, ok := type_info_base(info).variant.(Type_Info_Relative_Slice)