Browse Source

Add slice.map_keys, slice.map_values, slice.map_entries, slice.map_entry_infos

gingerBill 4 years ago
parent
commit
a07d199a48
2 changed files with 86 additions and 4 deletions
  1. 5 4
      core/reflect/map.odin
  2. 81 0
      core/slice/map.odin

+ 5 - 4
core/reflect/map.odin

@@ -6,7 +6,7 @@ _ :: runtime;
 _ :: mem;
 _ :: mem;
 
 
 Map_Entry_Info :: struct(Key, Value: typeid) {
 Map_Entry_Info :: struct(Key, Value: typeid) {
-	hash:  u64,
+	hash:  uintptr,
 	key:   Key,
 	key:   Key,
 	value: Value,
 	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);
 	gs := type_info_base(info.generated_struct).variant.(Type_Info_Struct);
 	ed := type_info_base(gs.types[1]).variant.(Type_Info_Dynamic_Array);
 	ed := type_info_base(gs.types[1]).variant.(Type_Info_Dynamic_Array);
 	entry_type := ed.elem.variant.(Type_Info_Struct);
 	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);
 	entry_size := uintptr(ed.elem_size);
 
 
 	entries = make(type_of(entries), rm.entries.len);
 	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 {
 	for i in 0..<rm.entries.len {
 		header := (^runtime.Map_Entry_Header)(data);
 		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)^;
 		value := (^V)(data + value_offset)^;
 
 
 		entries[i] = {hash, key, value};
 		entries[i] = {hash, key, value};

+ 81 - 0
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;
+}