diff options
| author | gingerBill <bill@gingerbill.org> | 2021-01-06 11:21:22 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-01-06 11:21:22 +0000 |
| commit | a07d199a48b8373aef1db4ad34ecee1fffa37dec (patch) | |
| tree | 3c9223305d14d32ad1c32fc2227363bc79042f83 | |
| parent | fa0e4c129426de79cfe28ee3e21bb5e851cedbff (diff) | |
Add slice.map_keys, slice.map_values, slice.map_entries, slice.map_entry_infos
| -rw-r--r-- | core/reflect/map.odin | 9 | ||||
| -rw-r--r-- | core/slice/map.odin | 81 |
2 files changed, 86 insertions, 4 deletions
diff --git a/core/reflect/map.odin b/core/reflect/map.odin index eb5b420a2..169370726 100644 --- a/core/reflect/map.odin +++ b/core/reflect/map.odin @@ -6,7 +6,7 @@ _ :: runtime; _ :: mem; Map_Entry_Info :: struct(Key, Value: typeid) { - hash: u64, + hash: uintptr, key: Key, value: Value, } @@ -19,7 +19,8 @@ map_entry_info_slice :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> gs := type_info_base(info.generated_struct).variant.(Type_Info_Struct); ed := type_info_base(gs.types[1]).variant.(Type_Info_Dynamic_Array); entry_type := ed.elem.variant.(Type_Info_Struct); - value_offset := entry_type.offsets[2]; + key_offset := entry_type.offsets[2]; + value_offset := entry_type.offsets[3]; entry_size := uintptr(ed.elem_size); entries = make(type_of(entries), rm.entries.len); @@ -28,8 +29,8 @@ map_entry_info_slice :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> for i in 0..<rm.entries.len { header := (^runtime.Map_Entry_Header)(data); - hash := header.key.hash; - key := (^K)(&header.key.key)^; + hash := header.hash; + key := (^K)(data + key_offset)^; value := (^V)(data + value_offset)^; entries[i] = {hash, key, value}; diff --git a/core/slice/map.odin b/core/slice/map.odin new file mode 100644 index 000000000..b9ec795a5 --- /dev/null +++ b/core/slice/map.odin @@ -0,0 +1,81 @@ +package slice + +import "intrinsics" +import "core:runtime" +import "core:mem" + +_ :: intrinsics; +_ :: runtime; +_ :: mem; + +map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K) { + keys = make(type_of(keys), len(m), allocator); + i := 0; + for key in m { + keys[i] = key; + i += 1; + } + return; +} +map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (values: []V) { + values = make(type_of(values), len(m), allocator); + i := 0; + for _, value in m { + values[i] = value; + i += 1; + } + return; +} + +Map_Entry :: struct(Key, Value: typeid) { + key: Key, + value: Value, +} + +Map_Entry_Info :: struct(Key, Value: typeid) { + hash: uintptr, + key: Key, + value: Value, +} + + +map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry(K, V)) { + entries = make(type_of(entries), len(m), allocator); + i := 0; + for key, value in m { + entries[i].key = key; + entries[i].value = value; + i += 1; + } + return; +} + +map_entry_infos :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry_Info(K, V)) #no_bounds_check { + m := m; + rm := (^mem.Raw_Map)(&m); + + info := runtime.type_info_base(type_info_of(M)).variant.(runtime.Type_Info_Map); + gs := runtime.type_info_base(info.generated_struct).variant.(runtime.Type_Info_Struct); + ed := runtime.type_info_base(gs.types[1]).variant.(runtime.Type_Info_Dynamic_Array); + entry_type := ed.elem.variant.(runtime.Type_Info_Struct); + key_offset := entry_type.offsets[2]; + value_offset := entry_type.offsets[3]; + entry_size := uintptr(ed.elem_size); + + entries = make(type_of(entries), rm.entries.len); + + data := uintptr(rm.entries.data); + for i in 0..<rm.entries.len { + header := (^runtime.Map_Entry_Header)(data); + + hash := header.hash; + key := (^K)(data + key_offset)^; + value := (^V)(data + value_offset)^; + + entries[i] = {hash, key, value}; + + data += entry_size; + } + + return; +} |