From 4e370e6ed8d6cfe3dee306dfbc298ba68722f12e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 23 Nov 2020 15:53:49 +0000 Subject: Add `equal` procedure field to `runtime.Type_Info_Struct` --- core/reflect/reflect.odin | 78 +++++++++++++++++++++++++++++++++++++++++++++++ core/runtime/core.odin | 5 +++ 2 files changed, 83 insertions(+) (limited to 'core') diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 947a10771..df183e2fd 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -1206,3 +1206,81 @@ as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) { return; } + + +not_equal :: proc(a, b: any) -> bool { + return !equal(a, b); +} +equal :: proc(a, b: any) -> bool { + if a == nil && b == nil { + return true; + } + + if a.id != b.id { + return false; + } + + if a.data == b.data { + return true; + } + + t := type_info_of(a.id); + if .Comparable not_in t.flags { + return false; + } + + if t.size == 0 { + return true; + } + + if .Simple_Compare in t.flags { + return mem.compare_byte_ptrs((^byte)(a.data), (^byte)(b.data), t.size) == 0; + } + + t = runtime.type_info_core(t); + + #partial switch v in t.variant { + case Type_Info_String: + if v.is_cstring { + x := string((^cstring)(a.data)^); + y := string((^cstring)(b.data)^); + return x == y; + } else { + x := (^string)(a.data)^; + y := (^string)(b.data)^; + return x == y; + } + + case Type_Info_Array: + for i in 0.. bool; Type_Info_Struct :: struct { types: []^Type_Info, names: []string, @@ -97,6 +99,9 @@ Type_Info_Struct :: struct { is_packed: bool, is_raw_union: bool, custom_align: bool, + + equal: Type_Struct_Equal_Proc, // set only when the struct has .Comparable set but does not have .Simple_Compare set + // These are only set iff this structure is an SOA structure soa_kind: Type_Info_Struct_Soa_Kind, soa_base_type: ^Type_Info, -- cgit v1.2.3