iterator.odin 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package reflect
  2. import "core:runtime"
  3. iterate_array :: proc(val: any, it: ^int) -> (elem: any, index: int, ok: bool) {
  4. if val == nil || it == nil {
  5. return
  6. }
  7. ti := type_info_base(type_info_of(val.id))
  8. #partial switch info in ti.variant {
  9. case Type_Info_Pointer:
  10. if ptr := (^rawptr)(val.data)^; ptr != nil {
  11. return iterate_array(any{ptr, info.elem.id}, it)
  12. }
  13. case Type_Info_Array:
  14. if it^ < info.count {
  15. elem.data = rawptr(uintptr(val.data) + uintptr(it^ * info.elem_size))
  16. elem.id = info.elem.id
  17. ok = true
  18. it^ += 1
  19. }
  20. case Type_Info_Slice:
  21. array := (^runtime.Raw_Slice)(val.data)
  22. if it^ < array.len {
  23. elem.data = rawptr(uintptr(array.data) + uintptr(it^ * info.elem_size))
  24. elem.id = info.elem.id
  25. ok = true
  26. it^ += 1
  27. }
  28. case Type_Info_Dynamic_Array:
  29. array := (^runtime.Raw_Dynamic_Array)(val.data)
  30. if it^ < array.len {
  31. elem.data = rawptr(uintptr(array.data) + uintptr(it^ * info.elem_size))
  32. elem.id = info.elem.id
  33. ok = true
  34. it^ += 1
  35. }
  36. }
  37. return
  38. }
  39. iterate_map :: proc(val: any, it: ^int) -> (key, value: any, ok: bool) {
  40. if val == nil || it == nil {
  41. return
  42. }
  43. ti := type_info_base(type_info_of(val.id))
  44. #partial switch info in ti.variant {
  45. case Type_Info_Pointer:
  46. if ptr := (^rawptr)(val.data)^; ptr != nil {
  47. return iterate_map(any{ptr, info.elem.id}, it)
  48. }
  49. case Type_Info_Map:
  50. if info.map_info == nil {
  51. break
  52. }
  53. rm := (^runtime.Raw_Map)(val.data)
  54. ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(rm^, info.map_info)
  55. for /**/ ; it^ < int(runtime.map_cap(rm^)); it^ += 1 {
  56. if hash := hs[it^]; runtime.map_hash_is_valid(hash) {
  57. key_ptr := runtime.map_cell_index_dynamic(ks, info.map_info.ks, uintptr(it^))
  58. value_ptr := runtime.map_cell_index_dynamic(vs, info.map_info.vs, uintptr(it^))
  59. key.data = rawptr(key_ptr)
  60. value.data = rawptr(value_ptr)
  61. key.id = info.key.id
  62. value.id = info.value.id
  63. ok = true
  64. break
  65. }
  66. }
  67. }
  68. return
  69. }