mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 22:28:46 +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;
|
eq :: equal;
|
||||||
ne :: not_equal;
|
ne :: not_equal;
|
||||||
|
|
||||||
not_equal :: proc(a, b: any) -> bool {
|
DEFAULT_EQUAL_MAX_RECURSION_LEVEL :: 32;
|
||||||
return !equal(a, b);
|
|
||||||
|
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 {
|
if a == nil && b == nil {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1307,6 +1309,11 @@ equal :: proc(a, b: any) -> bool {
|
|||||||
if .Simple_Compare in t.flags {
|
if .Simple_Compare in t.flags {
|
||||||
return mem.compare_byte_ptrs((^byte)(a.data), (^byte)(b.data), t.size) == 0;
|
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);
|
t = runtime.type_info_core(t);
|
||||||
|
|
||||||
@@ -1321,23 +1328,25 @@ equal :: proc(a, b: any) -> bool {
|
|||||||
y := (^string)(b.data)^;
|
y := (^string)(b.data)^;
|
||||||
return x == y;
|
return x == y;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
case Type_Info_Array:
|
case Type_Info_Array:
|
||||||
for i in 0..<v.count {
|
for i in 0..<v.count {
|
||||||
x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i));
|
x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i));
|
||||||
y := rawptr(uintptr(b.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 false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
case Type_Info_Enumerated_Array:
|
case Type_Info_Enumerated_Array:
|
||||||
for i in 0..<v.count {
|
for i in 0..<v.count {
|
||||||
x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i));
|
x := rawptr(uintptr(a.data) + uintptr(v.elem_size*i));
|
||||||
y := rawptr(uintptr(b.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 false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
case Type_Info_Struct:
|
case Type_Info_Struct:
|
||||||
if v.equal != nil {
|
if v.equal != nil {
|
||||||
return v.equal(a.data, b.data);
|
return v.equal(a.data, b.data);
|
||||||
@@ -1346,11 +1355,57 @@ equal :: proc(a, b: any) -> bool {
|
|||||||
x := rawptr(uintptr(a.data) + offset);
|
x := rawptr(uintptr(a.data) + offset);
|
||||||
y := rawptr(uintptr(b.data) + offset);
|
y := rawptr(uintptr(b.data) + offset);
|
||||||
id := v.types[i].id;
|
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 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;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user