aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-01-06 11:21:22 +0000
committergingerBill <bill@gingerbill.org>2021-01-06 11:21:22 +0000
commita07d199a48b8373aef1db4ad34ecee1fffa37dec (patch)
tree3c9223305d14d32ad1c32fc2227363bc79042f83 /core
parentfa0e4c129426de79cfe28ee3e21bb5e851cedbff (diff)
Add slice.map_keys, slice.map_values, slice.map_entries, slice.map_entry_infos
Diffstat (limited to 'core')
-rw-r--r--core/reflect/map.odin9
-rw-r--r--core/slice/map.odin81
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;
+}