iterator.odin 2.0 KB

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