mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Merge pull request #4030 from Kelimion/struct_field_count
Add `reflect.struct_field_count` that returns the number of fields in a struct type
This commit is contained in:
@@ -496,6 +496,64 @@ struct_field_offsets :: proc(T: typeid) -> []uintptr {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Struct_Field_Count_Method :: enum {
|
||||||
|
Top_Level,
|
||||||
|
Using,
|
||||||
|
Recursive,
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Counts the number of fields in a struct
|
||||||
|
|
||||||
|
This procedure returns the number of fields in a struct, counting in one of three ways:
|
||||||
|
- .Top_Level: Only counts the top-level fields
|
||||||
|
- .Using: Same count as .Top_Level, and adds the field count of any `using s: Struct` it encounters (in addition to itself)
|
||||||
|
- .Recursive: The count of all top-level fields, plus the count of any child struct's fields, recursively
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
- T: The struct type
|
||||||
|
- method: The counting method
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- The `count`, enumerated using the `method`, which will be `0` if the type is not a struct
|
||||||
|
|
||||||
|
Example:
|
||||||
|
symbols_loaded, ok := dynlib.initialize_symbols(&game_api, "game.dll")
|
||||||
|
symbols_expected := reflect.struct_field_count(Game_Api) - API_PRIVATE_COUNT
|
||||||
|
|
||||||
|
if symbols_loaded != symbols_expected {
|
||||||
|
fmt.eprintf("Expected %v symbols, got %v", symbols_expected, symbols_loaded)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@(require_results)
|
||||||
|
struct_field_count :: proc(T: typeid, method := Struct_Field_Count_Method.Top_Level) -> (count: int) {
|
||||||
|
ti := runtime.type_info_base(type_info_of(T))
|
||||||
|
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
|
||||||
|
switch method {
|
||||||
|
case .Top_Level:
|
||||||
|
return int(s.field_count)
|
||||||
|
|
||||||
|
case .Using:
|
||||||
|
count = int(s.field_count)
|
||||||
|
for type, i in s.types[:s.field_count] {
|
||||||
|
if s.usings[i] {
|
||||||
|
count += struct_field_count(type.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case .Recursive:
|
||||||
|
count = int(s.field_count)
|
||||||
|
for type in s.types[:s.field_count] {
|
||||||
|
count += struct_field_count(type.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
case: return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
|
struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
|
||||||
ti := runtime.type_info_base(type_info_of(T))
|
ti := runtime.type_info_base(type_info_of(T))
|
||||||
|
|||||||
Reference in New Issue
Block a user