diff options
| author | gingerBill <bill@gingerbill.org> | 2021-09-03 12:00:43 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-09-03 12:00:43 +0100 |
| commit | 11ae87cc2fec12d5bda0052ecc29d91d60b68a22 (patch) | |
| tree | f388a647e9ff8df114727163466148544d7242cd /core | |
| parent | b0f1b1ca166df86938d0352f8705acd0ecae8d28 (diff) | |
Add `including_indirect_array_recursion` argument to `reflect.equal`
Diffstat (limited to 'core')
| -rw-r--r-- | core/reflect/reflect.odin | 69 |
1 files 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..<v.count { x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i)); y := rawptr(uintptr(b.data) + uintptr(v.elem_size*i)); - if !equal(any{x, v.elem.id}, any{y, v.elem.id}) { + if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level) { return false; } } + return true; case Type_Info_Enumerated_Array: for i in 0..<v.count { x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i)); y := rawptr(uintptr(b.data) + uintptr(v.elem_size*i)); - if !equal(any{x, v.elem.id}, any{y, v.elem.id}) { + if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level) { return false; } } + return true; case Type_Info_Struct: if v.equal != nil { return v.equal(a.data, b.data); @@ -1346,11 +1355,57 @@ equal :: proc(a, b: any) -> 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..<array_a.len { + x := rawptr(uintptr(array_a.data) + uintptr(v.elem_size*i)); + y := rawptr(uintptr(array_b.data) + uintptr(v.elem_size*i)); + if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level+1) { + return false; + } + } + return true; + case Type_Info_Dynamic_Array: + if !including_indirect_array_recursion { + break; + } + array_a := (^mem.Raw_Dynamic_Array)(a.data); + array_b := (^mem.Raw_Dynamic_Array)(b.data); + if array_a.len != array_b.len { + return false; + } + if array_a.data == array_b.data { + return true; + } + for i in 0..<array_a.len { + x := rawptr(uintptr(array_a.data) + uintptr(v.elem_size*i)); + y := rawptr(uintptr(array_b.data) + uintptr(v.elem_size*i)); + if !equal(any{x, v.elem.id}, any{y, v.elem.id}, including_indirect_array_recursion, recursion_level+1) { + return false; + } + } + return true; } return true; |