diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 2d717f41f1..e7ff07c278 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -393,6 +393,16 @@ pub fn (a []byte) contains(val byte) bool { return false } +// TODO generic +pub fn (a []u16) contains(val u16) bool { + for aa in a { + if aa == val { + return true + } + } + return false +} + // TODO generic fn (ar []int) contains(val int) bool { for s in ar { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 926784a3d0..edcfb3f989 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2392,9 +2392,10 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { else {} } if left_sym.kind == .function { - g.write('_IN(u64, ') + g.write('_IN(voidptr, ') } else { - styp := g.typ(g.table.mktyp(left_type)) + elem_type := right_sym.array_info().elem_type + styp := g.typ(g.table.mktyp(elem_type)) g.write('_IN($styp, ') } g.expr(node.left) diff --git a/vlib/v/gen/cheaders.v b/vlib/v/gen/cheaders.v index ec31f8433b..23082f6a01 100644 --- a/vlib/v/gen/cheaders.v +++ b/vlib/v/gen/cheaders.v @@ -241,6 +241,20 @@ void* g_live_info = NULL; #define _IN(typ, val, arr) array_##typ##_contains(arr, val) #define _IN_MAP(val, m) map_exists(m, val) +// these macros have corresponding implementations in builtin/int.v with different signedness +#define array_i8_contains(a, b) array_byte_contains(a, (byte)(b)) +#define array_i16_contains(a, b) array_u16_contains(a, (u16)(b)) +#define array_u32_contains(a, b) array_int_contains(a, (int)(b)) +#define array_i64_contains(a, b) array_u64_contains(a, (u64)(b)) +#define array_rune_contains(a, b) array_int_contains(a, (int)(b)) +#define array_f32_contains(a, b) array_int_contains(a, *(int*)&((f32[]){(b)})) +#define array_f64_contains(a, b) array_u64_contains(a, *(u64*)&((f64[]){(b)})) +#ifdef TARGET_IS_64BIT +#define array_voidptr_contains(a, b) array_u64_contains(a, (u64)(b)) +#else +#define array_voidptr_contains(a, b) array_int_contains(a, (int)(b)) +#endif + // unsigned/signed comparisons static inline bool _us32_gt(uint32_t a, int32_t b) { return a > INT32_MAX || (int32_t)a > b; } static inline bool _us32_ge(uint32_t a, int32_t b) { return a >= INT32_MAX || (int32_t)a >= b; } diff --git a/vlib/v/tests/in_expression_test.v b/vlib/v/tests/in_expression_test.v index 886c371788..8ad2f37475 100644 --- a/vlib/v/tests/in_expression_test.v +++ b/vlib/v/tests/in_expression_test.v @@ -219,3 +219,36 @@ fn test_in_array_init() { assert 1 !in []int{} assert [1] in [[1], [2]] } + +fn test_in_expression_numeric() { + b := [byte(2), 4, 7] + b2 := [i8(3), -4, 9] + s := [u16(6), 1, 0] + s2 := [i16(34), -17, 45] + i := [5, 7, 9] + i2 := [u32(65), 12, 9] + l := [u64(54), 23, 1] + l2 := [i64(-45), 8, 2] + f := [f32(12.5), 0, -17.25] + f2 := [1.0625, 3, 17.125] + assert byte(4) in b + assert 3 !in b + assert -4 in b2 + assert i8(5) !in b2 + assert 1 in s + assert u16(3) !in s + assert 45 in s2 + assert i16(0) !in s2 + assert 7 in i + assert 8 !in i + assert 12 in i2 + assert u32(13) !in i2 + assert u64(1) in l + assert 2 !in l + assert -45 in l2 + assert i64(-17) !in l2 + assert -17.25 in f + assert f32(1) !in f + assert 1.0625 in f2 + assert 3.5 !in f2 +}