mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-03 19:52:30 +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
|
||||
}
|
||||
|
||||
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)
|
||||
struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
|
||||
ti := runtime.type_info_base(type_info_of(T))
|
||||
|
||||
Reference in New Issue
Block a user