iterator.odin 2.0 KB

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