mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-30 09:54:45 +00:00
Add including_indirect_array_recursion argument to reflect.equal
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user