map.odin 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package slice
  2. import "intrinsics"
  3. import "core:runtime"
  4. import "core:mem"
  5. _ :: intrinsics;
  6. _ :: runtime;
  7. _ :: mem;
  8. map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K) {
  9. keys = make(type_of(keys), len(m), allocator);
  10. i := 0;
  11. for key in m {
  12. keys[i] = key;
  13. i += 1;
  14. }
  15. return;
  16. }
  17. map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (values: []V) {
  18. values = make(type_of(values), len(m), allocator);
  19. i := 0;
  20. for _, value in m {
  21. values[i] = value;
  22. i += 1;
  23. }
  24. return;
  25. }
  26. Map_Entry :: struct($Key, $Value: typeid) {
  27. key: Key,
  28. value: Value,
  29. }
  30. Map_Entry_Info :: struct($Key, $Value: typeid) {
  31. hash: uintptr,
  32. key: Key,
  33. value: Value,
  34. }
  35. map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry(K, V)) {
  36. entries = make(type_of(entries), len(m), allocator);
  37. i := 0;
  38. for key, value in m {
  39. entries[i].key = key;
  40. entries[i].value = value;
  41. i += 1;
  42. }
  43. return;
  44. }
  45. map_entry_infos :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry_Info(K, V)) #no_bounds_check {
  46. m := m;
  47. rm := (^mem.Raw_Map)(&m);
  48. info := runtime.type_info_base(type_info_of(M)).variant.(runtime.Type_Info_Map);
  49. gs := runtime.type_info_base(info.generated_struct).variant.(runtime.Type_Info_Struct);
  50. ed := runtime.type_info_base(gs.types[1]).variant.(runtime.Type_Info_Dynamic_Array);
  51. entry_type := ed.elem.variant.(runtime.Type_Info_Struct);
  52. key_offset := entry_type.offsets[2];
  53. value_offset := entry_type.offsets[3];
  54. entry_size := uintptr(ed.elem_size);
  55. entries = make(type_of(entries), rm.entries.len);
  56. data := uintptr(rm.entries.data);
  57. for i in 0..<rm.entries.len {
  58. header := (^runtime.Map_Entry_Header)(data);
  59. hash := header.hash;
  60. key := (^K)(data + key_offset)^;
  61. value := (^V)(data + value_offset)^;
  62. entries[i] = {hash, key, value};
  63. data += entry_size;
  64. }
  65. return;
  66. }