mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: allow ==
to be user defined if !=
is auto generated and vice versa (#8286)
This commit is contained in:
parent
39e5f6e9df
commit
8a59ffb4b7
@ -3171,13 +3171,42 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||
}
|
||||
g.expr(node.right)
|
||||
g.write(')')
|
||||
} else if node.op in [.eq, .ne] && left_sym.kind == .struct_ && right_sym.kind == .struct_
|
||||
&& has_eq_overloaded&& has_ne_overloaded {
|
||||
ptr_typ := g.gen_struct_equality_fn(left_type)
|
||||
if node.op == .eq {
|
||||
g.write('${ptr_typ}_struct_eq(')
|
||||
} else if node.op == .ne {
|
||||
g.write('!${ptr_typ}_struct_eq(')
|
||||
} else if node.op in [.eq, .ne] && left_sym.kind == .struct_ && right_sym.kind == .struct_ {
|
||||
if has_eq_overloaded && !has_ne_overloaded {
|
||||
// Define `!=` as negation of Autogenerated `==`
|
||||
styp := g.typ(left_type)
|
||||
if node.op == .eq {
|
||||
g.write('!${styp}__ne(')
|
||||
} else if node.op == .ne {
|
||||
g.write('${styp}__ne(')
|
||||
}
|
||||
}
|
||||
if !has_eq_overloaded && has_ne_overloaded {
|
||||
// Define `==` as negation of Autogenerated `!=`
|
||||
styp := g.typ(left_type)
|
||||
if node.op == .ne {
|
||||
g.write('!${styp}__eq(')
|
||||
} else if node.op == .eq {
|
||||
g.write('${styp}__eq(')
|
||||
}
|
||||
}
|
||||
if !has_eq_overloaded && !has_ne_overloaded {
|
||||
// Overload both User defined `==` and `!=`
|
||||
styp := g.typ(left_type)
|
||||
if node.op == .eq {
|
||||
g.write('${styp}__eq(')
|
||||
} else if node.op == .ne {
|
||||
g.write('${styp}__ne(')
|
||||
}
|
||||
}
|
||||
if has_eq_overloaded && has_ne_overloaded {
|
||||
// Auto generate both `==` and `!=`
|
||||
ptr_typ := g.gen_struct_equality_fn(left_type)
|
||||
if node.op == .eq {
|
||||
g.write('${ptr_typ}_struct_eq(')
|
||||
} else if node.op == .ne {
|
||||
g.write('!${ptr_typ}_struct_eq(')
|
||||
}
|
||||
}
|
||||
if node.left_type.is_ptr() {
|
||||
g.write('*')
|
||||
|
15
vlib/v/tests/struct_eq_op_only_test.v
Normal file
15
vlib/v/tests/struct_eq_op_only_test.v
Normal file
@ -0,0 +1,15 @@
|
||||
struct User {
|
||||
name string
|
||||
num int
|
||||
}
|
||||
|
||||
fn (u User) == (u1 User) bool {
|
||||
return u.name == u1.name
|
||||
}
|
||||
|
||||
fn test_eq_op() {
|
||||
u1 := User{'Joe', 23}
|
||||
u2 := User{'Joe', 24}
|
||||
assert u1 == u2
|
||||
assert (u1 != u2) == false
|
||||
}
|
15
vlib/v/tests/sturct_ne_op_only_test.v
Normal file
15
vlib/v/tests/sturct_ne_op_only_test.v
Normal file
@ -0,0 +1,15 @@
|
||||
struct User {
|
||||
name string
|
||||
num int
|
||||
}
|
||||
|
||||
fn (u User) != (u1 User) bool {
|
||||
return u.num != u1.num
|
||||
}
|
||||
|
||||
fn test_eq_op() {
|
||||
u1 := User{'Joe', 23}
|
||||
u2 := User{'Joe', 24}
|
||||
assert u1 != u2
|
||||
assert (u1 == u2) == false
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user