map.odin 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. package reflect
  2. import "core:runtime"
  3. import "core:mem"
  4. _ :: runtime;
  5. _ :: mem;
  6. Map_Entry_Info :: struct($Key, $Value: typeid) {
  7. hash: uintptr,
  8. key: Key,
  9. value: Value,
  10. }
  11. map_entry_info_slice :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry_Info(K, V)) #no_bounds_check {
  12. m := m;
  13. rm := (^mem.Raw_Map)(&m);
  14. info := type_info_base(type_info_of(M)).variant.(Type_Info_Map);
  15. gs := type_info_base(info.generated_struct).variant.(Type_Info_Struct);
  16. ed := type_info_base(gs.types[1]).variant.(Type_Info_Dynamic_Array);
  17. entry_type := ed.elem.variant.(Type_Info_Struct);
  18. key_offset := entry_type.offsets[2];
  19. value_offset := entry_type.offsets[3];
  20. entry_size := uintptr(ed.elem_size);
  21. entries = make(type_of(entries), rm.entries.len);
  22. data := uintptr(rm.entries.data);
  23. for i in 0..<rm.entries.len {
  24. header := (^runtime.Map_Entry_Header)(data);
  25. hash := header.hash;
  26. key := (^K)(data + key_offset)^;
  27. value := (^V)(data + value_offset)^;
  28. entries[i] = {hash, key, value};
  29. data += entry_size;
  30. }
  31. return entries;
  32. }