From 7c255f0ff274f604e15a9234c3b81bb5c9ba67a2 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 18 Dec 2021 16:07:25 +0800 Subject: [PATCH] builtin, cgen: fix array of map init with default value (#12885) --- vlib/builtin/array.v | 15 +++++++ vlib/v/gen/c/array.v | 7 +++- vlib/v/tests/array_of_map_with_default_test.v | 42 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/array_of_map_with_default_test.v diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 961cac6591..ff1b12a213 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -72,6 +72,21 @@ fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array) a return arr } +fn __new_array_with_map_default(mylen int, cap int, elm_size int, val map) array { + cap_ := if cap < mylen { mylen } else { cap } + mut arr := array{ + element_size: elm_size + data: unsafe { malloc(cap_ * elm_size) } + len: mylen + cap: cap_ + } + for i in 0 .. arr.len { + val_clone := unsafe { val.clone() } + unsafe { arr.set_unsafe(i, &val_clone) } + } + return arr +} + // Private function, used by V (`nums := [1, 2, 3]`) fn new_array_from_c_array(len int, cap int, elm_size int, c_array voidptr) array { cap_ := if cap < len { len } else { cap } diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index d264a4c7c7..380ad4fd1a 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -106,6 +106,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { noscan := g.check_noscan(elem_type.typ) if node.exprs.len == 0 { is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default + is_default_map := elem_type.unaliased_sym.kind == .map && node.has_default if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression g.inside_lambda = true tmp := g.new_tmp_var() @@ -118,6 +119,8 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { g.write('$ret_typ $tmp =') if is_default_array { g.write('__new_array_with_array_default${noscan}(') + } else if is_default_map { + g.write('__new_array_with_map_default${noscan}(') } else { g.write('__new_array_with_default${noscan}(') } @@ -182,6 +185,8 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } if is_default_array { g.write('__new_array_with_array_default${noscan}(') + } else if is_default_map { + g.write('__new_array_with_map_default${noscan}(') } else { g.write('__new_array_with_default${noscan}(') } @@ -202,7 +207,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { } else { g.write('sizeof($elem_styp), ') } - if is_default_array { + if is_default_array || is_default_map { g.write('($elem_styp[]){') g.expr(node.default_expr) g.write('}[0])') diff --git a/vlib/v/tests/array_of_map_with_default_test.v b/vlib/v/tests/array_of_map_with_default_test.v new file mode 100644 index 0000000000..307286fdbf --- /dev/null +++ b/vlib/v/tests/array_of_map_with_default_test.v @@ -0,0 +1,42 @@ +fn init_a(n_rows int) []map[int]int { + mut tally := []map[int]int{} + for _ in 0 .. n_rows { + tally << map[int]int{} + } + return tally +} + +fn init_b(n_rows int) []map[int]int { + mut tally := []map[int]int{len: n_rows, init: map[int]int{}} + return tally +} + +pub fn tallys_in_array(indexs []int, values [][]int, init fn (int) []map[int]int) []map[int]int { + mut tally := init(indexs.len) + for row in 0 .. values.len { + for i, index in indexs { + tally[i][values[row][index]]++ + } + } + return tally +} + +fn test_array_of_map_with_default() { + indexs := [0, 1] + values := [[1, 201], [1, 3], [1, 201], [1, 3]] + + out1 := tallys_in_array(indexs, values, init_a) + println(out1) + out2 := tallys_in_array(indexs, values, init_b) + println(out2) + + mut maps := []map[int]int{} + maps << map[int]int{} + maps << map[int]int{} + maps[0][1] = 4 + maps[1][3] = 2 + maps[1][201] = 2 + + assert out1 == maps + assert out2 == maps +}