aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-09-03 12:00:43 +0100
committergingerBill <bill@gingerbill.org>2021-09-03 12:00:43 +0100
commit11ae87cc2fec12d5bda0052ecc29d91d60b68a22 (patch)
treef388a647e9ff8df114727163466148544d7242cd /core
parentb0f1b1ca166df86938d0352f8705acd0ecae8d28 (diff)
Add `including_indirect_array_recursion` argument to `reflect.equal`
Diffstat (limited to 'core')
-rw-r--r--core/reflect/reflect.odin69
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;