vxx2 / vlib / v / tests / array_slice_buffer_mark_test.v
44 lines · 41 sloc · 1.14 KB · 5ad37a5a8656c438c68dabd31c9d36467390e046
Raw
1// Regression test for https://github.com/vlang/v/issues/27507
2// `array.slice()` marks the source buffer's data header (`has_slices`) so a later
3// grow/delete of the parent does copy-on-grow instead of mutating a buffer that a
4// live slice still references. The marking was made cheaper (inlined header lookup,
5// store only when not already set); this test guards that the behavior is unchanged.
6
7fn test_live_slice_survives_parent_grow() {
8 mut a := [1, 2, 3, 4, 5]
9 s := a[1..4]
10 assert s == [2, 3, 4]
11 // growing the parent must copy, leaving the slice intact
12 for i in 0 .. 200 {
13 a << i
14 }
15 a[2] = 999
16 assert s == [2, 3, 4]
17}
18
19fn test_repeated_transient_slices_of_same_buffer() {
20 mut buf := []u8{len: 0, cap: 256}
21 for i in 0 .. 256 {
22 buf << u8(i)
23 }
24 mut acc := u64(0)
25 for _ in 0 .. 10000 {
26 w := buf[8..buf.len] // read-only window, dropped immediately
27 for b in w {
28 acc += b
29 }
30 }
31 // 10000 iterations * sum(8..256)
32 mut one := u64(0)
33 for j := 8; j < 256; j++ {
34 one += u64(j)
35 }
36 assert acc == one * 10000
37}
38
39fn test_slice_of_slice() {
40 a := [10, 20, 30, 40, 50]
41 s := a[1..5] // [20,30,40,50]
42 b := s[1..3] // [30,40]
43 assert b == [30, 40]
44}
45