map.odin 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package slice
  2. import "core:intrinsics"
  3. import "core:runtime"
  4. _ :: intrinsics
  5. _ :: runtime
  6. map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K, err: runtime.Allocator_Error) {
  7. keys = make(type_of(keys), len(m), allocator) or_return
  8. i := 0
  9. for key in m {
  10. keys[i] = key
  11. i += 1
  12. }
  13. return
  14. }
  15. map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (values: []V, err: runtime.Allocator_Error) {
  16. values = make(type_of(values), len(m), allocator) or_return
  17. i := 0
  18. for _, value in m {
  19. values[i] = value
  20. i += 1
  21. }
  22. return
  23. }
  24. Map_Entry :: struct($Key, $Value: typeid) {
  25. key: Key,
  26. value: Value,
  27. }
  28. Map_Entry_Info :: struct($Key, $Value: typeid) {
  29. hash: uintptr,
  30. key: Key,
  31. value: Value,
  32. }
  33. map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry(K, V), err: runtime.Allocator_Error) {
  34. entries = make(type_of(entries), len(m), allocator) or_return
  35. i := 0
  36. for key, value in m {
  37. entries[i].key = key
  38. entries[i].value = value
  39. i += 1
  40. }
  41. return
  42. }
  43. map_entry_infos :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry_Info(K, V)) #no_bounds_check {
  44. m := m
  45. rm := (^runtime.Raw_Map)(&m)
  46. info := type_info_base(type_info_of(M)).variant.(Type_Info_Map)
  47. if info.map_info != nil {
  48. entries = make(type_of(entries), len(m), allocator) or_return
  49. map_cap := uintptr(cap(m))
  50. ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(rm^, info.map_info)
  51. entry_index := 0
  52. for bucket_index in 0..<map_cap {
  53. if hash := hs[bucket_index]; runtime.map_hash_is_valid(hash) {
  54. key := runtime.map_cell_index_dynamic(ks, &info.map_info.ks, bucket_index)
  55. value := runtime.map_cell_index_dynamic(vs, &info.map_info.vs, bucket_index)
  56. entries[entry_index].hash = hash
  57. entries[entry_index].key = (^K)(key)^
  58. entries[entry_index].value = (^V)(value)^
  59. entry_index += 1
  60. }
  61. }
  62. }
  63. return
  64. }