From 11ae87cc2fec12d5bda0052ecc29d91d60b68a22 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 3 Sep 2021 12:00:43 +0100 Subject: [PATCH] Add `including_indirect_array_recursion` argument to `reflect.equal` --- core/reflect/reflect.odin | 69 +++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 881f32b6e..6e2748e88 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -1279,10 +1279,12 @@ as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) { eq :: equal; ne :: not_equal; -not_equal :: proc(a, b: any) -> bool { - return !equal(a, b); +DEFAULT_EQUAL_MAX_RECURSION_LEVEL :: 32; + +not_equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool { + return !equal(a, b, including_indirect_array_recursion, recursion_level); } -equal :: proc(a, b: any) -> bool { +equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_level := 0) -> bool { if a == nil && b == nil { return true; } @@ -1307,6 +1309,11 @@ equal :: proc(a, b: any) -> bool { if .Simple_Compare in t.flags { return mem.compare_byte_ptrs((^byte)(a.data), (^byte)(b.data), t.size) == 0; } + + including_indirect_array_recursion := including_indirect_array_recursion; + if recursion_level >= DEFAULT_EQUAL_MAX_RECURSION_LEVEL { + including_indirect_array_recursion = false; + } t = runtime.type_info_core(t); @@ -1321,23 +1328,25 @@ equal :: proc(a, b: any) -> bool { y := (^string)(b.data)^; return x == y; } - + return true; case Type_Info_Array: for i in 0.. bool { x := rawptr(uintptr(a.data) + offset); y := rawptr(uintptr(b.data) + offset); id := v.types[i].id; - if !equal(any{x, id}, any{y, id}) { + if !equal(any{x, id}, any{y, id}, including_indirect_array_recursion, recursion_level) { return false; } } + return true; } + case Type_Info_Union: + if v.equal != nil { + return v.equal(a.data, b.data); + } + return false; + case Type_Info_Slice: + if !including_indirect_array_recursion { + break; + } + array_a := (^mem.Raw_Slice)(a.data); + array_b := (^mem.Raw_Slice)(b.data); + if array_a.len != array_b.len { + return false; + } + if array_a.data == array_b.data { + return true; + } + for i in 0..