aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-11-10 12:27:12 +0000
committergingerBill <bill@gingerbill.org>2022-11-10 12:27:12 +0000
commitf6fc3ebe37bb1d2ab23bfbddc4ca04ffdb7781bb (patch)
treecff5f981ef08bf2c66db21a7d6e436c896003766 /core
parent5c106abe3fd1850c3880fcd6753e3e2273c1eded (diff)
Add reflect/iterator.odin
Diffstat (limited to 'core')
-rw-r--r--core/reflect/iterator.odin76
1 files changed, 76 insertions, 0 deletions
diff --git a/core/reflect/iterator.odin b/core/reflect/iterator.odin
new file mode 100644
index 000000000..62baff06e
--- /dev/null
+++ b/core/reflect/iterator.odin
@@ -0,0 +1,76 @@
+package reflect
+
+import "core:runtime"
+
+iterate_array :: proc(val: any, it: ^int) -> (elem: any, index: int, ok: bool) {
+ if val == nil || it == nil {
+ return
+ }
+
+ ti := type_info_base(type_info_of(val.id))
+ #partial switch info in ti.variant {
+ case Type_Info_Pointer:
+ if ptr := (^rawptr)(val.data)^; ptr != nil {
+ return iterate_array(any{ptr, info.elem.id}, it)
+ }
+ case Type_Info_Array:
+ if it^ < info.count {
+ elem.data = rawptr(uintptr(val.data) + uintptr(it^ * info.elem_size))
+ elem.id = info.elem.id
+ ok = true
+ it^ += 1
+ }
+ case Type_Info_Slice:
+ array := (^runtime.Raw_Slice)(val.data)
+ if it^ < array.len {
+ elem.data = rawptr(uintptr(array.data) + uintptr(it^ * info.elem_size))
+ elem.id = info.elem.id
+ ok = true
+ it^ += 1
+ }
+ case Type_Info_Dynamic_Array:
+ array := (^runtime.Raw_Dynamic_Array)(val.data)
+ if it^ < array.len {
+ elem.data = rawptr(uintptr(array.data) + uintptr(it^ * info.elem_size))
+ elem.id = info.elem.id
+ ok = true
+ it^ += 1
+ }
+ }
+
+ return
+}
+
+iterate_map :: proc(val: any, it: ^int) -> (key, value: any, ok: bool) {
+ if val == nil || it == nil {
+ return
+ }
+ ti := type_info_base(type_info_of(val.id))
+ #partial switch info in ti.variant {
+ case Type_Info_Pointer:
+ if ptr := (^rawptr)(val.data)^; ptr != nil {
+ return iterate_map(any{ptr, info.elem.id}, it)
+ }
+ case Type_Info_Map:
+ if info.map_info == nil {
+ break
+ }
+ rm := (^runtime.Raw_Map)(val.data)
+ ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(rm^, info.map_info)
+ for /**/ ; it^ < int(runtime.map_cap(rm^)); it^ += 1 {
+ if hash := hs[it^]; runtime.map_hash_is_valid(hash) {
+ key_ptr := runtime.map_cell_index_dynamic(ks, info.map_info.ks, uintptr(it^))
+ value_ptr := runtime.map_cell_index_dynamic(vs, info.map_info.vs, uintptr(it^))
+
+ key.data = rawptr(key_ptr)
+ value.data = rawptr(value_ptr)
+ key.id = info.key.id
+ value.id = info.value.id
+ ok = true
+ return
+ }
+
+ }
+ }
+ return
+} \ No newline at end of file