v / vlib / builtin / array_test.v
2026 lines · 1795 sloc · 40.78 KB · 8085eeb8ebe3481226f918ac91615e4c8a12eb8d
Raw
1fn test_pointer() {
2 mut arr := []&int{}
3 a := 1
4 b := 2
5 c := 3
6 arr << &a
7 arr << &b
8 arr << &c
9 assert *arr[0] == 1
10 arr[1] = &c
11 assert *arr[1] == 3
12 mut d_arr := [arr] // [][]&int
13 d_arr << arr
14 assert *d_arr[0][1] == 3
15 println(*d_arr[0][1])
16 assert *d_arr[1][0] == 1
17}
18
19fn test_assign() {
20 mut arr := [2, 4, 8, 16, 32, 64, 128]
21 arr[0] = 2
22 arr[1] &= 255
23 arr[2] |= 255
24 arr[3] <<= 4
25 arr[4] >>= 4
26 arr[5] %= 5
27 arr[6] ^= 3
28 assert arr[0] == 2
29 assert arr[1] == 4 & 255
30 assert arr[2] == 8 | 255
31 assert arr[3] == 16 << 4
32 assert arr[4] == 32 >> 4
33 assert arr[5] == 64 % 5
34 assert arr[6] == 128 ^ 3
35}
36
37fn test_ints() {
38 mut a := [1, 5, 2, 3]
39 assert a.len == 4
40 assert a[0] == 1
41 assert a[2] == 2
42 assert a.last() == 3
43 a << 4
44 assert a.len == 5
45 assert a[4] == 4
46 assert a.last() == 4
47 s := a.str()
48 assert s == '[1, 5, 2, 3, 4]'
49 assert a[1] == 5
50 assert a.last() == 4
51}
52
53fn test_deleting() {
54 mut a := [1, 5, 2, 3, 4]
55 assert a.len == 5
56 assert a.str() == '[1, 5, 2, 3, 4]'
57 a.delete(0)
58 assert a.str() == '[5, 2, 3, 4]'
59 assert a.len == 4
60 a.delete(1)
61 assert a.str() == '[5, 3, 4]'
62 assert a.len == 3
63 a.delete(a.len - 1)
64 assert a.str() == '[5, 3]'
65 assert a.len == 2
66}
67
68fn test_slice_delete() {
69 mut a := [1.5, 2.5, 3.25, 4.5, 5.75]
70 b := unsafe { a[2..4] }
71 a.delete(0)
72 assert a == [2.5, 3.25, 4.5, 5.75]
73 assert b == [3.25, 4.5]
74 a = [3.75, 4.25, -1.5, 2.25, 6.0]
75 c := unsafe { a[..3] }
76 a.delete(2)
77 assert a == [3.75, 4.25, 2.25, 6.0]
78 assert c == [3.75, 4.25, -1.5]
79}
80
81fn test_delete_last_uses_in_place_fast_path_for_unique_arrays() {
82 mut a := [1, 2, 3, 4]
83 old_data := a.data
84 a.delete(a.len - 1)
85 assert a == [1, 2, 3]
86 assert a.data == old_data
87 assert a.cap == 4
88 unsafe {
89 assert (&int(a.data))[a.len] == 0
90 }
91}
92
93fn test_delete_last_detaches_when_a_slice_exists() {
94 mut a := [1, 2, 3, 4]
95 b := unsafe { a[..a.len] }
96 old_data := a.data
97 a.delete(a.len - 1)
98 assert a == [1, 2, 3]
99 assert b == [1, 2, 3, 4]
100 assert a.data != old_data
101}
102
103fn test_delete_last_clears_removed_slot_for_unique_arrays() {
104 mut a := [1, 2, 3, 4]
105 old_data := a.data
106 a.delete_last()
107 assert a == [1, 2, 3]
108 assert a.data == old_data
109 assert a.cap == 4
110 unsafe {
111 assert (&int(a.data))[a.len] == 0
112 }
113}
114
115fn test_delete_many() {
116 mut a := [1, 2, 3, 4, 5, 6, 7, 8, 9]
117 b := unsafe { a[2..6] }
118 a.delete_many(4, 3)
119 assert a == [1, 2, 3, 4, 8, 9]
120 assert b == [3, 4, 5, 6]
121 c := unsafe { a[..a.len] }
122 a.delete_many(2, 0) // this should just clone
123 a[1] = 17
124 assert a == [1, 17, 3, 4, 8, 9]
125 assert c == [1, 2, 3, 4, 8, 9]
126 a.delete_many(0, a.len)
127 assert a == []int{}
128}
129
130fn int_array_with_spare_cap() []int {
131 mut a := []int{len: 5, cap: 8}
132 for i in 0 .. a.len {
133 a[i] = i + 1
134 }
135 return a
136}
137
138fn test_delete_many_unique_arrays_use_in_place_fast_path() {
139 mut a := int_array_with_spare_cap()
140 old_data := a.data
141 a.delete_many(1, 2)
142 assert a == [1, 4, 5]
143 assert a.data == old_data
144 assert a.cap == 8
145 unsafe {
146 assert (&int(a.data))[a.len] == 0
147 assert (&int(a.data))[a.len + 1] == 0
148 }
149}
150
151fn test_insert_detaches_parent_with_existing_slice() {
152 mut a := int_array_with_spare_cap()
153 mut b := unsafe { a[1..4] }
154 a.insert(0, 99)
155 assert a == [99, 1, 2, 3, 4, 5]
156 assert b == [2, 3, 4]
157 b[0] = 42
158 assert a == [99, 1, 2, 3, 4, 5]
159}
160
161fn test_slice_pop_detaches_immediately() {
162 mut a := int_array_with_spare_cap()
163 mut b := unsafe { a[1..4] }
164 last := b.pop()
165 b[0] = 20
166 b << 99
167 assert last == 4
168 assert a == [1, 2, 3, 4, 5]
169 assert b == [20, 3, 99]
170}
171
172fn test_slice_trim_detaches_immediately() {
173 mut a := int_array_with_spare_cap()
174 mut b := unsafe { a[1..4] }
175 b.trim(1)
176 b[0] = 20
177 b << 99
178 assert a == [1, 2, 3, 4, 5]
179 assert b == [20, 99]
180}
181
182fn test_slice_clear_detaches_immediately() {
183 mut a := int_array_with_spare_cap()
184 mut b := unsafe { a[1..4] }
185 b.clear()
186 b << 77
187 assert a == [1, 2, 3, 4, 5]
188 assert b == [77]
189}
190
191fn test_short() {
192 a := [1, 2, 3]
193 assert a.len == 3
194 assert a.cap == 3
195 assert a[0] == 1
196 assert a[1] == 2
197 assert a[2] == 3
198}
199
200fn test_large() {
201 mut a := [0].repeat(0)
202 for i in 0 .. 10000 {
203 a << i
204 }
205 assert a.len == 10000
206 assert a[234] == 234
207}
208
209struct Chunk {
210 val string
211}
212
213struct Kkk {
214 q []Chunk
215}
216
217fn test_empty() {
218 mut chunks := []Chunk{}
219 a := Chunk{}
220 assert chunks.len == 0
221 chunks << a
222 assert chunks.len == 1
223 chunks = []
224 assert chunks.len == 0
225 chunks << a
226 assert chunks.len == 1
227}
228
229fn test_push() {
230 mut a := []int{}
231 a << 1
232 a << 3
233 assert a[1] == 3
234 assert a.str() == '[1, 3]'
235}
236
237fn test_insert() {
238 mut a := [1, 2]
239 a.insert(0, 3)
240 assert a[0] == 3
241 assert a[2] == 2
242 assert a.len == 3
243 a.insert(1, 4)
244 assert a[1] == 4
245 assert a[2] == 1
246 assert a.len == 4
247 a.insert(4, 5)
248 assert a[4] == 5
249 assert a[3] == 2
250 assert a.len == 5
251 mut b := []f64{}
252 assert b.len == 0
253 b.insert(0, f64(1.1))
254 assert b.len == 1
255 assert b[0] == f64(1.1)
256}
257
258fn test_insert_many() {
259 mut a := [3, 4]
260 a.insert(0, [1, 2])
261 assert a == [1, 2, 3, 4]
262 b := [5, 6]
263 a.insert(1, b)
264 assert a == [1, 5, 6, 2, 3, 4]
265}
266
267fn test_prepend() {
268 mut a := []int{}
269 assert a.len == 0
270 a.prepend(1)
271 assert a.len == 1
272 assert a[0] == 1
273 mut b := []f64{}
274 assert b.len == 0
275 b.prepend(f64(1.1))
276 assert b.len == 1
277 assert b[0] == f64(1.1)
278}
279
280fn test_prepend_many() {
281 mut a := [3, 4]
282 a.prepend([1, 2])
283 assert a == [1, 2, 3, 4]
284 b := [5, 6]
285 a.prepend(b)
286 assert a == [5, 6, 1, 2, 3, 4]
287}
288
289type Strings = []string
290
291fn test_aliases_of_array_insert() {
292 mut strs := Strings(['hi'])
293 strs.insert(0, '22')
294 assert strs == ['22', 'hi']
295 strs.insert(1, ['11'])
296 assert strs == ['22', '11', 'hi']
297}
298
299fn test_aliases_of_array_prepend() {
300 mut strs := Strings(['hi'])
301 strs.prepend('22')
302 assert strs == ['22', 'hi']
303 strs.prepend(['44', '33'])
304 assert strs == ['44', '33', '22', 'hi']
305}
306
307fn test_strings() {
308 a := ['a', 'b', 'c']
309 assert a.str() == "['a', 'b', 'c']"
310}
311
312/*
313fn test_compare_ints() {
314 assert compare_ints(1, 2) == -1
315 assert compare_ints(2, 1) == 1
316 assert compare_ints(0, 0) == 0
317
318 a := 1
319 b := 2
320 assert compare_ints(a, b) == -1
321 assert compare_ints(b, a) == 1
322 assert compare_ints(a, a) == 0
323}
324*/
325
326fn test_repeat_int() {
327 a := [1234].repeat(5)
328 // dump(a)
329 assert a.len == 5
330 for x in a {
331 assert x == 1234
332 }
333}
334
335fn test_repeat_f64() {
336 a := [1.1].repeat(10)
337 // dump(a)
338 assert a.len == 10
339 assert a[0] == 1.1
340 assert a[5] == 1.1
341 assert a[9] == 1.1
342}
343
344fn test_repeat_f32() {
345 a := [f32(1.1)].repeat(10)
346 // dump(a)
347 assert a.len == 10
348 assert a[0] == f32(1.1)
349 assert a[5] == f32(1.1)
350 assert a[9] == f32(1.1)
351}
352
353fn test_repeat_i64() {
354 a := [i64(-123)].repeat(10)
355 // dump(a)
356 assert a.len == 10
357 assert a[0] == -123
358 assert a[5] == -123
359 assert a[9] == -123
360}
361
362fn test_repeat_u64() {
363 a := [u64(123)].repeat(10)
364 assert a[0] == 123
365 assert a[5] == 123
366 assert a[9] == 123
367}
368
369fn test_repeat_several_ints() {
370 a := [1, 2].repeat(2)
371 // dump(a)
372 assert a.len == 4
373 assert a[0] == 1
374 assert a[1] == 2
375 assert a[2] == 1
376 assert a[3] == 2
377}
378
379fn test_repeat_several_strings_2() {
380 a := ['1', 'abc'].repeat(2)
381 // dump(a)
382 assert a.len == 4
383 assert a[0] == '1'
384 assert a[1] == 'abc'
385 assert a[2] == '1'
386 assert a[3] == 'abc'
387}
388
389fn test_repeat_several_strings_0() {
390 mut a := ['1', 'abc'].repeat(0)
391 // dump(a)
392 assert a.len == 0
393 a << 'abc'
394 assert a[0] == 'abc'
395}
396
397fn test_deep_repeat() {
398 mut a3 := [[[1, 1], [2, 2], [3, 3]], [[4, 4], [5, 5], [6, 6]]]
399 r := a3.repeat(3)
400 // dump(r)
401 a3[1][1][0] = 17
402 assert r == [
403 [[1, 1], [2, 2], [3, 3]],
404 [[4, 4], [5, 5], [6, 6]],
405 [[1, 1], [2, 2], [3, 3]],
406 [[4, 4], [5, 5], [6, 6]],
407 [[1, 1], [2, 2], [3, 3]],
408 [[4, 4], [5, 5], [6, 6]],
409 ]
410 assert a3 == [[[1, 1], [2, 2], [3, 3]], [[4, 4], [17, 5], [6, 6]]]
411}
412
413interface RepeatClonedInterfaceValue {
414 get_value() int
415mut:
416 change()
417}
418
419struct RepeatClonedStructValue {
420mut:
421 value int
422}
423
424fn (sample RepeatClonedStructValue) get_value() int {
425 return sample.value
426}
427
428fn (mut sample RepeatClonedStructValue) change() {
429 sample.value += 2
430}
431
432fn test_repeat_clones_interface_elements() {
433 mut samples := [
434 RepeatClonedInterfaceValue(RepeatClonedStructValue{
435 value: 1
436 }),
437 RepeatClonedInterfaceValue(RepeatClonedStructValue{
438 value: 2
439 }),
440 ].repeat(2)
441 samples[0].change()
442 samples[1].change()
443 samples[1].change()
444 assert samples[0].get_value() == 3
445 assert samples[1].get_value() == 6
446 assert samples[2].get_value() == 1
447 assert samples[3].get_value() == 2
448}
449
450fn test_right() {
451 a := [1, 2, 3, 4]
452 c := a[1..a.len]
453 d := a[1..]
454 assert c[0] == 2
455 assert c[1] == 3
456 assert d[0] == 2
457 assert d[1] == 3
458}
459
460fn test_left() {
461 a := [1, 2, 3]
462 c := a[0..2]
463 d := a[..2]
464 assert c[0] == 1
465 assert c[1] == 2
466 assert d[0] == 1
467 assert d[1] == 2
468}
469
470fn test_slice() {
471 a := [1, 2, 3, 4]
472 b := a[2..4]
473 assert b.len == 2
474 assert a[1..2].len == 1
475 assert a.len == 4
476}
477
478fn test_push_many() {
479 mut a := [1, 2, 3]
480 b := [4, 5, 6]
481 a << b
482 assert a.len == 6
483 assert a[0] == 1
484 assert a[3] == 4
485 assert a[5] == 6
486}
487
488fn test_push_many_self_append_with_growth() {
489 mut a := [u8(`a`), `b`, `c`]
490 a << a
491 assert a.bytestr() == 'abcabc'
492 a << a
493 assert a.bytestr() == 'abcabcabcabc'
494}
495
496fn test_reverse() {
497 a := [1, 2, 3, 4]
498 b := ['test', 'array', 'reverse']
499 c := a.reverse()
500 println(c)
501 d := b.reverse()
502 for i, _ in c {
503 assert c[i] == a[a.len - i - 1]
504 }
505 for i, _ in d {
506 assert d[i] == b[b.len - i - 1]
507 }
508 e := []int{}
509 f := e.reverse()
510 assert f.len == 0
511}
512
513const c_n = 5
514
515struct Foooj {
516 a [5]int // c_n
517}
518
519fn test_fixed() {
520 mut nums := [4]int{}
521 // x := nums[1..3]
522 // assert x.len == 2
523 assert nums[0] == 0
524 assert nums[1] == 0
525 assert nums[2] == 0
526 assert nums[3] == 0
527 nums[1] = 7
528 assert nums[1] == 7
529 nums2 := [5]int{} // c_n
530 assert nums2[c_n - 1] == 0
531}
532
533fn modify(mut numbers []int) {
534 numbers[0] = 777
535}
536
537fn test_mut_slice() {
538 mut n := [1, 2, 3]
539 // modify(mut n)
540 modify(mut n[..2])
541 assert n[0] == 777
542 modify(mut n[2..])
543 assert n[2] == 777
544 println(n)
545}
546
547fn double_up(mut a []int) {
548 for i := 0; i < a.len; i++ {
549 a[i] = a[i] * 2
550 }
551}
552
553fn double_up_v2(mut a []int) {
554 for i, _ in a {
555 a[i] = a[i] * 2 // or val*2, doesn't matter
556 }
557}
558
559fn test_mut_arg() {
560 mut arr := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
561 double_up(mut arr)
562 assert arr.str() == '[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]'
563 arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
564 double_up_v2(mut arr)
565 assert arr.str() == '[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]'
566}
567
568fn test_clone() {
569 nums := [1, 2, 3, 4, 100]
570 _ = nums
571 nums2 := nums.clone()
572 assert nums2.len == 5
573 assert nums.str() == '[1, 2, 3, 4, 100]'
574 assert nums2.str() == '[1, 2, 3, 4, 100]'
575 assert nums[1..3].str() == '[2, 3]'
576}
577
578/*
579fn test_copy() {
580 a := [1, 2, 3]
581 b := a
582 assert b[0] == 1
583 assert b[1] == 2
584 assert b[2] == 3
585}
586*/
587fn test_multi_array_clone() {
588 // 2d array_int
589 mut a2_1 := [[1, 2, 3], [4, 5, 6]]
590 mut a2_2 := a2_1.clone()
591 a2_1[0][1] = 0
592 a2_2[1][0] = 0
593 assert a2_1 == [[1, 0, 3], [4, 5, 6]]
594 assert a2_2 == [[1, 2, 3], [0, 5, 6]]
595 // 2d array_string
596 mut b2_1 := [['1', '2', '3'], ['4', '5', '6']]
597 mut b2_2 := b2_1.clone()
598 b2_1[0][1] = '0'
599 b2_2[1][0] = '0'
600 assert b2_1 == [['1', '0', '3'], ['4', '5', '6']]
601 assert b2_2 == [['1', '2', '3'], ['0', '5', '6']]
602 // 3d array_int
603 mut a3_1 := [[[1, 1], [2, 2], [3, 3]], [[4, 4], [5, 5], [6, 6]]]
604 mut a3_2 := a3_1.clone()
605 a3_1[0][0][1] = 0
606 a3_2[0][1][0] = 0
607 assert a3_1 == [[[1, 0], [2, 2], [3, 3]], [[4, 4], [5, 5],
608 [6, 6]]]
609 assert a3_2 == [[[1, 1], [0, 2], [3, 3]], [[4, 4], [5, 5],
610 [6, 6]]]
611 // 3d array_string
612 mut b3_1 := [[['1', '1'], ['2', '2'], ['3', '3']], [['4', '4'],
613 ['5', '5'], ['6', '6']]]
614 mut b3_2 := b3_1.clone()
615 b3_1[0][0][1] = '0'
616 b3_2[0][1][0] = '0'
617 assert b3_1 == [[['1', '0'], ['2', '2'], ['3', '3']], [['4', '4'],
618 ['5', '5'], ['6', '6']]]
619 assert b3_2 == [[['1', '1'], ['0', '2'], ['3', '3']], [['4', '4'],
620 ['5', '5'], ['6', '6']]]
621}
622
623fn test_doubling() {
624 mut nums := [1, 2, 3, 4, 5]
625 for i in 0 .. nums.len {
626 nums[i] *= 2
627 }
628 println(nums.str())
629 assert nums.str() == '[2, 4, 6, 8, 10]'
630}
631
632struct Test2 {
633 one int
634 two int
635}
636
637struct Test {
638 a string
639mut:
640 b []Test2
641}
642
643fn (t Test2) str() string {
644 return '{${t.one} ${t.two}}'
645}
646
647fn (t Test) str() string {
648 return '{${t.a} ${t.b}}'
649}
650
651fn test_struct_print() {
652 mut a := Test{
653 a: 'Test'
654 b: []
655 }
656 b := Test2{
657 one: 1
658 two: 2
659 }
660 a.b << b
661 a.b << b
662 assert a.str() == '{Test [{1 2}, {1 2}]}'
663 assert b.str() == '{1 2}'
664 assert a.b.str() == '[{1 2}, {1 2}]'
665}
666
667fn test_single_element() {
668 mut a := [1]
669 a << 2
670 assert a.len == 2
671 assert a[0] == 1
672 assert a[1] == 2
673 println(a)
674}
675
676fn test_find_index() {
677 // string
678 a := ['v', 'is', 'great']
679 assert a.index('v') == 0
680 assert a.index('is') == 1
681 assert a.index('gre') == -1
682 // int
683 b := [1, 2, 3, 4]
684 assert b.index(1) == 0
685 assert b.index(4) == 3
686 assert b.index(5) == -1
687 // byte
688 c := [0x22, 0x33, 0x55]
689 assert c.index(0x22) == 0
690 assert c.index(0x55) == 2
691 assert c.index(0x99) == -1
692 // char
693 d := [`a`, `b`, `c`]
694 assert d.index(`b`) == 1
695 assert d.index(`c`) == 2
696 assert d.index(`u`) == -1
697}
698
699fn test_find_last_index() {
700 // string
701 a := ['v', 'is', 'great', 'is', 'k', 'm']
702 assert a.last_index('v') == 0
703 assert a.last_index('is') == 3
704 assert a.last_index('gre') == -1
705 // int
706 b := [1, 2, 3, 4, 0, 1, 2, 3, 0, 1, 2, 3]
707 assert b.last_index(1) == 9
708 assert b.last_index(4) == 3
709 assert b.last_index(5) == -1
710 // byte
711 c := [0x22, 0x33, 0x55, 0x22, 0x44, 0x55]
712 assert c.last_index(0x22) == 3
713 assert c.last_index(0x55) == 5
714 assert c.last_index(0x99) == -1
715 // char
716 d := [`a`, `b`, `c`, `e`, `a`, `b`, `c`, `k`]
717 assert d.last_index(`b`) == 5
718 assert d.last_index(`c`) == 6
719 assert d.last_index(`u`) == -1
720}
721
722fn test_multi() {
723 a := [[1, 2, 3], [4, 5, 6]]
724 assert a.len == 2
725 assert a[0].len == 3
726 assert a[0][0] == 1
727 assert a[0][2] == 3
728 assert a[1][2] == 6
729 b := [[[1, 2, 3], [4, 5, 6]], [[1, 2]]]
730 assert b[0][0][0] == 1
731}
732
733fn test_in() {
734 a := [1, 2, 3]
735 assert 1 in a
736 assert 2 in a
737 assert 3 in a
738 assert 4 !in a
739 assert 0 !in a
740 assert 0 !in a
741 assert 4 !in a
742 b := [1, 4, 0]
743 c := [3, 6, 2, 0]
744 assert 0 in b
745 assert 0 in c
746}
747
748fn sum(prev int, curr int) int {
749 return prev + curr
750}
751
752fn sub(prev int, curr int) int {
753 return prev - curr
754}
755
756fn filter_test_helper_1(a int) bool {
757 return a > 3
758}
759
760fn test_filter() {
761 a := [1, 2, 3, 4, 5, 6]
762 b := a.filter(it % 2 == 0)
763 assert b.len == 3
764 assert b[0] == 2
765 assert b[1] == 4
766 assert b[2] == 6
767 c := ['v', 'is', 'awesome']
768 d := c.filter(it.len > 1)
769 assert d[0] == 'is'
770 assert d[1] == 'awesome'
771 ////////
772 arr := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
773 println(arr.filter(it % 2 == 0 || it % 3 == 0))
774 assert true
775 assert [1, 2, 3].len == 3
776 mut mut_arr := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
777 mut_arr = mut_arr.filter(it < 4)
778 assert mut_arr.len == 3
779 assert a.filter(filter_test_helper_1) == [4, 5, 6]
780 assert [1, 5, 10].filter(filter_test_helper_1) == [5, 10]
781}
782
783fn test_anon_fn_filter() {
784 filter_num := fn (i int) bool {
785 return i % 2 == 0
786 }
787 assert [1, 2, 3, 4, 5].filter(filter_num) == [2, 4]
788}
789
790fn test_anon_fn_arg_filter() {
791 a := [1, 2, 3, 4].filter(fn (i int) bool {
792 return i % 2 == 0
793 })
794 assert a == [2, 4]
795}
796
797fn map_test_helper_1(i int) int {
798 return i * i
799}
800
801fn map_test_helper_2(i int, b string) int {
802 return i + b.len
803}
804
805fn map_test_helper_3(i int, b []string) int {
806 return i + b.map(it.len)[i % b.len]
807}
808
809fn test_map() {
810 nums := [1, 2, 3, 4, 5, 6]
811 strs := ['v', 'is', 'awesome']
812 // assert nums.map() == <error>
813 // assert nums.map(it, 'excessive') == <error>
814 // identity
815 assert nums.map(it) == [1, 2, 3, 4, 5, 6]
816 assert strs.map(it) == ['v', 'is', 'awesome']
817 assert nums.map(it - it) == [0, 0, 0, 0, 0, 0]
818 assert nums.map(it - it)[0] == 0
819 // type switch
820 assert nums.map(it * 10) == [10, 20, 30, 40, 50, 60]
821 assert nums.map(it * it) == [1, 4, 9, 16, 25, 36]
822 assert nums.map('${it}') == ['1', '2', '3', '4', '5', '6']
823 assert nums.map(it % 2 == 0) == [false, true, false, true, false, true]
824 assert strs.map(it.to_upper()) == ['V', 'IS', 'AWESOME']
825 assert strs.map(it == 'awesome') == [false, false, true]
826 assert strs.map(it.len in nums) == [true, true, false]
827 assert strs.map(int(7)) == [7, 7, 7]
828 // external func
829 assert nums.map(map_test_helper_1(it)) == [1, 4, 9, 16, 25, 36]
830 assert nums.map(map_test_helper_2(it, 'bb')) == [3, 4, 5, 6, 7, 8]
831 assert nums.map(map_test_helper_3(it, strs)) == [3, 9, 4, 6, 12, 7]
832 // empty array as input
833 assert []int{len: 0}.map(it * 2) == []
834 // nested maps (where it is of same type)
835 assert nums.map(strs.map(int(7)) == [7, 7, 7]) == [true, true, true, true, true, true]
836 assert nums.map('${it}' + strs.map('a')[0]) == ['1a', '2a', '3a', '4a', '5a', '6a']
837 assert nums.map(it + strs.map(int(7))[0]) == [8, 9, 10, 11, 12, 13]
838 assert nums.map(it + strs.map(it.len)[0]) == [2, 3, 4, 5, 6, 7]
839 assert strs.map(it.len + strs.map(it.len)[0]) == [2, 3, 8]
840 // nested (different it types)
841 assert strs.map(it[nums.map(it - it)[0]]) == [u8(`v`), `i`, `a`]
842 assert nums[0..3].map('${it}' + strs.map(it)[it - 1]) == ['1v', '2is', '3awesome']
843 assert nums.map(map_test_helper_1) == [1, 4, 9, 16, 25, 36]
844 assert [1, 5, 10].map(map_test_helper_1) == [1, 25, 100]
845 assert nums == [1, 2, 3, 4, 5, 6]
846 assert strs == ['v', 'is', 'awesome']
847}
848
849fn test_anon_fn_map() {
850 add_num := fn (i int) int {
851 return i + 1
852 }
853 assert [1, 2, 3].map(add_num) == [2, 3, 4]
854}
855
856fn test_multi_anon_fn_map() {
857 a := [1, 2, 3].map(fn (i int) int {
858 return i + 1
859 })
860 b := [1, 2, 3].map(fn (i int) int {
861 return i + 2
862 })
863 assert a == [2, 3, 4]
864 assert b == [3, 4, 5]
865}
866
867fn test_anon_fn_arg_map() {
868 a := [1, 2, 3].map(fn (i int) int {
869 return i + 1
870 })
871 assert a == [2, 3, 4]
872}
873
874fn test_anon_fn_arg_different_type_map() {
875 i_to_str := fn (i int) string {
876 return i.str()
877 }
878 a := [1, 2, 3].map(i_to_str)
879 assert a == ['1', '2', '3']
880}
881
882fn test_anon_fn_inline_different_type_map() {
883 a := [1, 2, 3].map(fn (i int) string {
884 return i.str()
885 })
886 assert a == ['1', '2', '3']
887}
888
889fn test_array_str() {
890 numbers := [1, 2, 3]
891 assert numbers == [1, 2, 3]
892 numbers2 := [numbers, [4, 5, 6]] // dup str() bug
893 println(numbers2)
894 assert true
895 assert numbers.str() == '[1, 2, 3]'
896 assert numbers2.str() == '[[1, 2, 3], [4, 5, 6]]'
897}
898
899struct User {
900 age int
901 name string
902}
903
904fn test_eq() {
905 assert [5, 6, 7] != [6, 7]
906 assert [`a`, `b`] == [`a`, `b`]
907 assert [User{
908 age: 22
909 name: 'bob'
910 }] == [User{
911 age: 22
912 name: 'bob'
913 }]
914 assert [{
915 'bob': 22
916 }, {
917 'tom': 33
918 }] == [{
919 'bob': 22
920 }, {
921 'tom': 33
922 }]
923 assert [[1, 2, 3], [4]] == [[1, 2, 3], [4]]
924}
925
926fn test_fixed_array_eq() {
927 a1 := [1, 2, 3]!
928 assert a1 == [1, 2, 3]!
929 assert a1 != [2, 3, 4]!
930
931 a2 := [[1, 2]!, [3, 4]!]!
932 assert a2 == [[1, 2]!, [3, 4]!]!
933 assert a2 != [[3, 4]!, [1, 2]!]!
934
935 // TODO: fixed arrays of dynamic arrays not yet supported in ARM64 backend
936 // a3 := [[1, 2], [3, 4]]!
937 // assert a3 == [[1, 2], [3, 4]]!
938 // assert a3 != [[1, 1], [2, 2]]!
939 // a4 := [[`a`, `b`], [`c`, `d`]]!
940 // assert a4 == [[`a`, `b`], [`c`, `d`]]!
941 // assert a4 != [[`c`, `a`], [`a`, `b`]]!
942 // a5 := [['aaa', 'bbb'], ['ccc', 'ddd']]!
943 // assert a5 == [['aaa', 'bbb'], ['ccc', 'ddd']]!
944 // assert a5 != [['abc', 'def'], ['ccc', 'ddd']]!
945 // a6 := [['aaa', 'bbb']!, ['ccc', 'ddd']!]!
946 // assert a6 == [['aaa', 'bbb']!, ['ccc', 'ddd']!]!
947 // assert a6 != [['aaa', 'bbb']!, ['aaa', 'ddd']!]!
948 // a7 := [[1, 2]!, [3, 4]!]
949 // assert a7 == [[1, 2]!, [3, 4]!]
950 // assert a7 != [[2, 3]!, [1, 2]!]
951 // a8 := [['aaa', 'bbb']!, ['ccc', 'ddd']!]
952 // assert a8 == [['aaa', 'bbb']!, ['ccc', 'ddd']!]
953 // assert a8 != [['bbb', 'aaa']!, ['cccc', 'dddd']!]
954}
955
956fn test_fixed_array_literal_eq() {
957 assert [1, 2, 3]! == [1, 2, 3]!
958 // TODO: fixed array literal != comparison in ARM64 backend
959 // assert [1, 1, 1]! != [1, 2, 3]!
960 // assert [[1, 2], [3, 4]]! == [[1, 2], [3, 4]]!
961 // assert [[1, 1], [2, 2]]! != [[1, 2], [3, 4]]!
962 // assert [[1, 1]!, [2, 2]!]! == [[1, 1]!, [2, 2]!]!
963 // assert [[1, 1]!, [2, 2]!]! != [[1, 2]!, [2, 3]!]!
964 // assert [[1, 1]!, [2, 2]!] == [[1, 1]!, [2, 2]!]
965 // assert [[1, 1]!, [2, 2]!] != [[1, 2]!, [2, 3]!]
966 // vfmt off
967 assert ([1, 2, 3]!) == [1, 2, 3]!
968 // vfmt on
969}
970
971fn test_sort() {
972 mut a := ['hi', '1', '5', '3']
973 a.sort()
974 assert a == ['1', '3', '5', 'hi']
975
976 mut nums := [67, -3, 108, 42, 7]
977 nums.sort()
978 assert nums == [-3, 7, 42, 67, 108]
979
980 nums.sort(a < b)
981 assert nums == [-3, 7, 42, 67, 108]
982
983 nums.sort(b < a)
984 assert nums == [108, 67, 42, 7, -3]
985
986 mut users := [User{22, 'Peter'}, User{20, 'Bob'}, User{25, 'Alice'}]
987 users.sort(a.age < b.age)
988 assert users[0].age == 20
989 assert users[1].age == 22
990 assert users[2].age == 25
991 assert users[0].name == 'Bob'
992 assert users[1].name == 'Peter'
993 assert users[2].name == 'Alice'
994
995 users.sort(a.age > b.age)
996 assert users[0].age == 25
997 assert users[1].age == 22
998 assert users[2].age == 20
999
1000 users.sort(b.age > a.age)
1001 assert users[0].age == 20
1002 assert users[1].age == 22
1003 assert users[2].age == 25
1004
1005 users.sort(a.name < b.name)
1006 assert users[0].name == 'Alice'
1007 assert users[1].name == 'Bob'
1008 assert users[2].name == 'Peter'
1009}
1010
1011fn test_sort_preserves_relative_order_for_equal_elements() {
1012 source := [User{4, 'B'}, User{4, 'A'}, User{5, 'C'}]
1013
1014 mut sorted := source.clone()
1015 sorted.sort(a.age > b.age)
1016 assert sorted[0].name == 'C'
1017 assert sorted[1].name == 'B'
1018 assert sorted[2].name == 'A'
1019
1020 copy := source.sorted(a.age > b.age)
1021 assert copy[0].name == 'C'
1022 assert copy[1].name == 'B'
1023 assert copy[2].name == 'A'
1024}
1025
1026fn test_sort_with_compare() {
1027 mut a := ['hi', '1', '5', '3']
1028 a.sort_with_compare(fn (a &string, b &string) int {
1029 if a < b {
1030 return -1
1031 }
1032 if a > b {
1033 return 1
1034 }
1035 return 0
1036 })
1037 assert a == ['1', '3', '5', 'hi']
1038}
1039
1040fn test_sort_with_compare_preserves_relative_order_for_equal_elements() {
1041 source := [User{4, 'B'}, User{4, 'A'}, User{5, 'C'}]
1042
1043 mut sorted := source.clone()
1044 sorted.sort_with_compare(fn (a &User, b &User) int {
1045 if a.age > b.age {
1046 return -1
1047 }
1048 if a.age < b.age {
1049 return 1
1050 }
1051 return 0
1052 })
1053 assert sorted[0].name == 'C'
1054 assert sorted[1].name == 'B'
1055 assert sorted[2].name == 'A'
1056
1057 copy := source.sorted_with_compare(fn (a &User, b &User) int {
1058 if a.age > b.age {
1059 return -1
1060 }
1061 if a.age < b.age {
1062 return 1
1063 }
1064 return 0
1065 })
1066 assert copy[0].name == 'C'
1067 assert copy[1].name == 'B'
1068 assert copy[2].name == 'A'
1069}
1070
1071fn test_rune_sort() {
1072 mut bs := [`f`, `e`, `d`, `b`, `c`, `a`]
1073 bs.sort()
1074 println(bs)
1075 assert bs == [`a`, `b`, `c`, `d`, `e`, `f`]
1076
1077 bs.sort(a > b)
1078 println(bs)
1079 assert bs == [`f`, `e`, `d`, `c`, `b`, `a`]
1080
1081 bs.sort(a < b)
1082 println(bs)
1083 assert bs == [`a`, `b`, `c`, `d`, `e`, `f`]
1084}
1085
1086fn test_sort_by_different_order_of_a_b() {
1087 mut x := [1, 2, 3]
1088 x.sort(a < b)
1089 println(x)
1090 assert x == [1, 2, 3]
1091
1092 mut y := [1, 2, 3]
1093 y.sort(b < a)
1094 println(y)
1095 assert y == [3, 2, 1]
1096}
1097
1098fn test_f32_sort() {
1099 mut f := [f32(50.0), 15, 1, 79, 38, 0, 27]
1100 f.sort()
1101 assert f == [f32(0.0), 1, 15, 27, 38, 50, 79]
1102
1103 f.sort(a < b)
1104 assert f == [f32(0.0), 1, 15, 27, 38, 50, 79]
1105
1106 f.sort(b > a)
1107 assert f == [f32(0.0), 1, 15, 27, 38, 50, 79]
1108
1109 f.sort(b < a)
1110 assert f == [f32(79.0), 50, 38, 27, 15, 1, 0]
1111
1112 f.sort(a > b)
1113 assert f == [f32(79.0), 50, 38, 27, 15, 1, 0]
1114}
1115
1116fn test_f64_sort() {
1117 mut f := [50.0, 15, 1, 79, 38, 0, 27]
1118 f.sort()
1119 assert f[0] == 0.0
1120 assert f[1] == 1.0
1121 assert f[6] == 79.0
1122}
1123
1124fn test_i64_sort() {
1125 mut f := [i64(50), 15, 1, 79, 38, 0, 27]
1126 f.sort()
1127 assert f[0] == 0
1128 assert f[1] == 1
1129 assert f[6] == 79
1130}
1131
1132fn test_sort_index_expr() {
1133 mut f := [[i64(50), 48], [i64(15)], [i64(1)], [i64(79)], [i64(38)],
1134 [i64(0)], [i64(27)]]
1135 // TODO: This currently gives "indexing pointer" error without unsafe
1136 unsafe {
1137 f.sort(a[0] < b[0])
1138 }
1139 assert f == [[i64(0)], [i64(1)], [i64(15)], [i64(27)], [i64(38)],
1140 [i64(50), 48], [i64(79)]]
1141}
1142
1143fn test_a_b_paras_sort() {
1144 mut arr_i := [1, 3, 2]
1145 arr_i.sort(a < b)
1146 println(arr_i)
1147 assert arr_i == [1, 2, 3]
1148 arr_i.sort(b < a)
1149 println(arr_i)
1150 assert arr_i == [3, 2, 1]
1151
1152 mut arr_f := [1.1, 3.3, 2.2]
1153 arr_f.sort(a < b)
1154 println(arr_f)
1155 assert arr_f == [1.1, 2.2, 3.3]
1156 arr_f.sort(b < a)
1157 println(arr_f)
1158 assert arr_f == [3.3, 2.2, 1.1]
1159}
1160
1161/*
1162fn test_for_last() {
1163 numbers := [1, 2, 3, 4]
1164 mut s := '['
1165 for num in numbers {
1166 s += '${num}'
1167 if !last {
1168 s += ', '
1169
1170 }
1171 }
1172 s += ']'
1173 assert s == '[1, 2, 3, 4]'
1174}
1175*/
1176struct Foo {
1177mut:
1178 bar []int
1179}
1180
1181fn test_in_struct() {
1182 mut baz := Foo{
1183 bar: [0, 0, 0]
1184 }
1185 baz.bar[0] += 2
1186 baz.bar[0]++
1187 assert baz.bar[0] == 3
1188}
1189
1190@[direct_array_access]
1191fn test_direct_modification() {
1192 mut foo := [2, 0, 5]
1193 foo[1] = 3
1194 foo[0] *= 7
1195 foo[1]--
1196 foo[2] -= 2
1197 assert foo[0] == 14
1198 assert foo[1] == 2
1199 assert foo[2] == 3
1200}
1201
1202fn test_bools() {
1203 println('test b')
1204 mut a := [true, false]
1205 a << true
1206 println(a)
1207}
1208
1209fn test_push_many_self() {
1210 mut actual_arr := [1, 2, 3, 4]
1211 actual_arr << actual_arr
1212 expected_arr := [1, 2, 3, 4, 1, 2, 3, 4]
1213 assert actual_arr.len == expected_arr.len
1214 for i in 0 .. actual_arr.len {
1215 assert actual_arr[i] == expected_arr[i]
1216 }
1217}
1218
1219fn test_for() {
1220 nums := [1, 2, 3]
1221 mut sum := 0
1222 for num in nums {
1223 sum += num
1224 }
1225 assert sum == 6
1226}
1227
1228fn test_clear() {
1229 mut arr := [1, 2, 3]
1230 assert arr.len == 3
1231 arr.clear()
1232 assert arr.len == 0
1233 arr << 3
1234 arr << 2
1235 arr << 1
1236 arr << 0
1237 assert arr.len == 4
1238 assert arr[0] == 3
1239 assert arr[1] == 2
1240 assert arr[2] == 1
1241 assert arr[3] == 0
1242 arr.clear()
1243 assert arr.len == 0
1244}
1245
1246fn test_trim() {
1247 mut arr := [1, 2, 3, 4, 5, 6, 7, 8, 9]
1248 assert arr.len == 9
1249 arr.trim(9)
1250 assert arr.len == 9
1251 assert arr.last() == 9
1252 arr.trim(7)
1253 assert arr.len == 7
1254 assert arr.last() == 7
1255 arr.trim(2)
1256 assert arr.len == 2
1257 assert arr.last() == 2
1258}
1259
1260@[manualfree]
1261fn test_drop() {
1262 mut a := [1, 2]
1263 a << 3 // pushing assures reallocation; a.cap now should be bigger:
1264 assert a.cap > 3
1265 // eprintln('>>> a.cap: ${a.cap} | a.len: ${a.len}')
1266
1267 a.drop(-1000)
1268 assert a == [1, 2, 3] // a.drop( negative ) should NOT modify the array
1269 // eprintln('>>> a.cap: ${a.cap} | a.len: ${a.len}')
1270
1271 a.drop(2)
1272 assert a == [3]
1273 assert a.cap > a.len
1274 // eprintln('>>> a.cap: ${a.cap} | a.len: ${a.len}')
1275
1276 a.drop(10)
1277 assert a == []
1278 assert a.cap > a.len
1279 // eprintln('>>> a.cap: ${a.cap} | a.len: ${a.len}')
1280
1281 a << 123
1282 a << 456
1283 a << 789
1284 // eprintln('>>> a.cap: ${a.cap} | a.len: ${a.len}')
1285 assert a == [123, 456, 789]
1286
1287 a.drop(10)
1288 assert a == []
1289 // eprintln('>>> a.cap: ${a.cap} | a.len: ${a.len}')
1290
1291 unsafe { a.free() } // test offset OK
1292}
1293
1294fn test_hex() {
1295 // array hex
1296 st := [u8(`V`), `L`, `A`, `N`, `G`]
1297 assert st.hex() == '564c414e47'
1298 assert st.hex().len == 10
1299 st1 := [u8(0x41)].repeat(100)
1300 assert st1.hex() == '41'.repeat(100)
1301}
1302
1303fn test_left_shift_precedence() {
1304 mut arr := []int{}
1305 arr << 1 + 1
1306 arr << 1 - 1
1307 arr << 2 / 1
1308 arr << 2 * 1
1309 assert arr[0] == 2
1310 assert arr[1] == 0
1311 assert arr[2] == 2
1312 assert arr[3] == 2
1313}
1314
1315fn test_array_with_cap() {
1316 a4 := []int{len: 1, cap: 10}
1317 assert a4.len == 1
1318 assert a4.cap == 10
1319 a5 := []int{len: 1, cap: 10}
1320 assert a5.len == 1
1321 assert a5.cap == 10
1322}
1323
1324fn test_multi_array_index() {
1325 mut a := [][]int{len: 2, init: []int{len: 3, init: 0}}
1326 a[0][0] = 1
1327 assert '${a}' == '[[1, 0, 0], [0, 0, 0]]'
1328 mut b := [[0].repeat(3)].repeat(2)
1329 b[0][0] = 1
1330 assert '${b}' == '[[1, 0, 0], [0, 0, 0]]'
1331}
1332
1333fn test_multi_array_default_init_preserves_noscan_rows() {
1334 $if gcboehm_opt ? {
1335 mut matrix := [][]f64{len: 2, init: []f64{len: 3, init: 0.0}}
1336 matrix[0][0] = 1.25
1337 assert matrix[0].flags.has(.noscan_data)
1338 assert matrix[1].flags.has(.noscan_data)
1339 assert matrix[0].data != matrix[1].data
1340 assert matrix[1][0] == 0.0
1341 }
1342}
1343
1344fn test_plus_assign_string() {
1345 mut a := ['']
1346 a[0] += 'abc'
1347 assert a == ['abc']
1348}
1349
1350fn mut_arr_with_eq_in_fn(mut a []int) {
1351 if a == [1, 2, 3, 4] {
1352 a[0] = 0
1353 }
1354 if [0, 2, 3, 4] == a {
1355 a[1] = 0
1356 }
1357 if !(a != [0, 0, 3, 4]) {
1358 a[2] = 0
1359 }
1360 if !([0, 0, 0, 4] != a) {
1361 a[3] = 0
1362 }
1363}
1364
1365fn test_mut_arr_with_eq_in_fn() {
1366 mut a := [1, 2, 3, 4]
1367 mut_arr_with_eq_in_fn(mut a)
1368 assert a == [0, 0, 0, 0]
1369}
1370
1371fn array_in_mut(mut a []int) {
1372 if 1 in a {
1373 a[0] = 2
1374 }
1375}
1376
1377fn test_array_in_mut() {
1378 mut a := [1, 2]
1379 array_in_mut(mut a)
1380 assert a == [2, 2]
1381}
1382
1383// test array delete in function with mut argument
1384fn delete_nums(mut arr []int) {
1385 arr.delete(0)
1386}
1387
1388fn test_array_delete_in_mut() {
1389 mut nums := [1, 2, 3]
1390 delete_nums(mut nums)
1391 assert nums == [2, 3]
1392}
1393
1394// test array add in function with mut argument
1395fn add_nums(mut arr []int) {
1396 arr << 4
1397}
1398
1399fn test_array_add_in_mut() {
1400 mut nums := [1, 2, 3]
1401 add_nums(mut nums)
1402 assert nums == [1, 2, 3, 4]
1403}
1404
1405fn test_reverse_in_place() {
1406 mut a := [1, 2, 3, 4]
1407 a.reverse_in_place()
1408 assert a == [4, 3, 2, 1]
1409 mut b := ['a', 'b', 'c']
1410 b.reverse_in_place()
1411 assert b == ['c', 'b', 'a']
1412 mut c := [[1, 2], [3, 4], [5, 6]]
1413 c.reverse_in_place()
1414 assert c == [[5, 6], [3, 4], [1, 2]]
1415}
1416
1417fn test_array_int_pop_left() {
1418 mut a := [1, 2, 3, 4, 5]
1419 b := unsafe { a[..5] } // full slice view
1420 assert a.len == 5
1421 first := a[0]
1422 x := a.pop_left()
1423 assert first == x
1424 assert a.len == 4
1425 assert a.cap == 4
1426 y := a.pop_left()
1427 assert y == 2
1428 a[0] = 100
1429 // NOTE: update a[0] also update b[2]
1430 assert b == [1, 2, 100, 4, 5]
1431
1432 mut one_elem := [1]
1433 one := one_elem.pop_left()
1434 assert one_elem.len == 0
1435 assert one_elem.cap == 0
1436 assert one == 1
1437}
1438
1439fn test_array_string_pop_left() {
1440 mut a := ['abc', 'def', 'xyz']
1441 assert a.len == 3
1442 x := a.first()
1443 y := a.pop_left()
1444 assert x == y
1445 assert a.pop_left() == 'def'
1446 assert a.pop_left() == 'xyz'
1447 assert a.len == 0
1448 assert a.cap == 0
1449}
1450
1451fn test_array_int_pop() {
1452 mut a := [1, 2, 3, 4, 5]
1453 assert a.len == 5
1454 x := a.last()
1455 y := a.pop()
1456 assert x == y
1457 assert a.len == 4
1458 z := a.pop()
1459 assert a.len == 3
1460 assert z == 4
1461 x1 := a.pop()
1462 x2 := a.pop()
1463 final := a.pop()
1464 assert final == 1
1465}
1466
1467fn test_array_string_pop() {
1468 mut a := ['abc', 'def', 'xyz']
1469 assert a.len == 3
1470 assert a.pop() == 'xyz'
1471 assert a.pop() == 'def'
1472 assert a.pop() == 'abc'
1473 assert a.len == 0
1474 assert a.cap == 3
1475}
1476
1477fn test_array_first() {
1478 a := [3]
1479 assert a.first() == 3
1480 b := [1, 2, 3, 4]
1481 assert b.first() == 1
1482 c := ['abc', 'def']
1483 assert c.first()[0] == `a`
1484 s := [Chunk{'a'}]
1485 assert s.first().val == 'a'
1486}
1487
1488fn test_array_last() {
1489 a := [3]
1490 assert a.last() == 3
1491 b := [1, 2, 3, 4]
1492 assert b.last() == 4
1493 c := ['abc', 'def']
1494 assert c.last()[0] == `d`
1495 s := [Chunk{'a'}]
1496 assert s.last().val == 'a'
1497}
1498
1499@[direct_array_access]
1500fn test_direct_array_access() {
1501 mut a := [11, 22, 33, 44]
1502 assert a[0] == 11
1503 assert a[2] == 33
1504 x := a[0]
1505 a[0] = 21
1506 a[1] += 2
1507 a[2] = x + 3
1508 a[3] -= a[1]
1509 assert a == [21, 24, 14, 20]
1510}
1511
1512@[direct_array_access]
1513fn test_direct_array_access_via_ptr() {
1514 mut b := [11, 22, 33, 44]
1515 unsafe {
1516 mut a := &b
1517 assert a[0] == 11
1518 assert a[2] == 33
1519 x := a[0]
1520 a[0] = 21
1521 a[1] += 2
1522 a[2] = x + 3
1523 a[3] -= a[1]
1524 assert a == [21, 24, 14, 20]
1525 }
1526}
1527
1528fn test_push_arr_string_free() {
1529 mut lines := ['hi']
1530 s := 'a' + 'b'
1531 lines << s
1532 // make sure the data in the array is valid after freeing the string
1533 unsafe { s.free() }
1534
1535 println(lines)
1536 assert lines.len == 2
1537 assert lines[0] == 'hi'
1538 assert lines[1] == 'ab'
1539}
1540
1541const grid_size_1 = 2
1542const grid_size_2 = 3
1543const grid_size_3 = 4
1544const cell_value = 123
1545
1546fn test_multidimensional_array_initialization_with_consts() {
1547 // TODO: module-level constants resolve to 0 in ARM64 backend
1548 // mut data := [][][]int{len: grid_size_1, init: [][]int{len: grid_size_2, init: []int{len: grid_size_3, init: cell_value}}}
1549 // assert data.len == grid_size_1
1550}
1551
1552fn test_byteptr_vbytes() {
1553 unsafe {
1554 bp := malloc(5)
1555 bp[0] = 1
1556 bp[1] = 2
1557 bp[2] = 3
1558 bp[3] = 4
1559 bp[4] = 255
1560 bytes := bp.vbytes(5)
1561 println(bytes)
1562 assert bytes.len == 5
1563 assert bytes[0] == 1
1564 assert bytes[1] == 2
1565 assert bytes[2] == 3
1566 assert bytes[3] == 4
1567 assert bytes[4] == 255
1568 }
1569}
1570
1571fn test_voidptr_vbytes() {
1572 unsafe {
1573 bp := malloc(3)
1574 bp[0] = 4
1575 bp[1] = 5
1576 bp[2] = 6
1577 bytes := voidptr(bp).vbytes(3)
1578 assert bytes.len == 3
1579 assert bytes[0] == 4
1580 assert bytes[1] == 5
1581 assert bytes[2] == 6
1582 println(bytes)
1583 }
1584}
1585
1586fn test_multi_array_prepend() {
1587 // TODO: nested array prepend type disambiguation in ARM64 backend
1588 // mut a := [][]int{}
1589 // a.prepend([1, 2, 3])
1590 // assert a == [[1, 2, 3]]
1591}
1592
1593fn test_multi_array_insert() {
1594 // TODO: nested array insert type disambiguation in ARM64 backend
1595 // mut a := [][]int{}
1596 // a.insert(0, [1, 2, 3])
1597 // assert a == [[1, 2, 3]]
1598 mut b := [][]int{}
1599 b.insert(0, [[1, 2, 3]])
1600 assert b == [[1, 2, 3]]
1601}
1602
1603fn test_multi_array_in() {
1604 a := [[1]]
1605 println([1] in a)
1606 assert [1] in a
1607}
1608
1609fn test_any_type_array_contains() {
1610 a := [true, false]
1611 assert a.contains(true)
1612 assert true in a
1613 assert a.contains(false)
1614 assert false in a
1615 b := [i64(2), 3, 4]
1616 assert b.contains(i64(3))
1617 assert 5 !in b
1618 c := [[1], [2]]
1619 assert c.contains([1])
1620 assert [2] in c
1621 assert [3] !in c
1622}
1623
1624struct Person {
1625 name string
1626 nums []int
1627 kv map[string]string
1628}
1629
1630fn test_struct_array_of_multi_type_in() {
1631 // TODO: struct equality with nested arrays/maps not working in ARM64 backend
1632 // ivan := Person{name: 'ivan', nums: [1, 2, 3], kv: {'aaa': '111'}}
1633 // people := [Person{name: 'ivan', nums: [1, 2, 3], kv: {'aaa': '111'}}]
1634 // assert ivan in people
1635}
1636
1637fn test_struct_array_of_multi_type_index() {
1638 // TODO: struct equality with nested arrays/maps not working in ARM64 backend
1639}
1640
1641// disabled_struct_array_of_multi_type_index: requires struct eq with nested arrays/maps
1642
1643struct Coord {
1644 x int
1645 y int
1646 z int
1647}
1648
1649fn test_array_struct_contains() {
1650 mut coords := []Coord{}
1651 coord_1 := Coord{
1652 x: 1
1653 y: 2
1654 z: -1
1655 }
1656 coords << coord_1
1657 exists := coord_1 in coords
1658 not_exists := coord_1 !in coords
1659 println('`exists`: ${exists} and `not exists`: ${not_exists}')
1660 assert exists == true
1661 assert not_exists == false
1662}
1663
1664fn test_array_struct_ref_contains() {
1665 mut coords := []&Coord{}
1666 coord_1 := &Coord{
1667 x: 1
1668 y: 2
1669 z: -1
1670 }
1671 coords << coord_1
1672 exists := coord_1 in coords
1673 println(exists)
1674 assert exists == true
1675}
1676
1677fn test_array_struct_ref_index() {
1678 mut coords := []&Coord{}
1679 coord_1 := &Coord{
1680 x: 1
1681 y: 2
1682 z: -1
1683 }
1684 coords << coord_1
1685 println(coords.index(coord_1))
1686 assert coords.index(coord_1) == 0
1687}
1688
1689fn test_array_of_array_append() {
1690 mut x := [][]int{len: 4}
1691 println(x) // OK
1692 x[2] << 123 // RTE
1693 println(x)
1694 assert '${x}' == '[[], [], [123], []]'
1695}
1696
1697fn test_array_of_map_insert() {
1698 // TODO: Map_string_int_str not generated for ARM64 backend
1699 // mut x := []map[string]int{len: 4}
1700 // println(x)
1701 // x[2]['123'] = 123
1702 // assert '${x}' == "[{}, {}, {'123': 123}, {}]"
1703}
1704
1705fn test_multi_fixed_array_init() {
1706 // TODO: multi-dimensional fixed array init crashes in ARM64 backend
1707 // a := [3][3]int{}
1708 // assert '${a}' == '[[0, 0, 0], [0, 0, 0], [0, 0, 0]]'
1709}
1710
1711struct Numbers {
1712 odds []int
1713 evens []int
1714}
1715
1716fn test_array_of_multi_filter() {
1717 arr := [1, 2, 3, 4, 5]
1718 nums := Numbers{
1719 odds: arr.filter(it % 2 == 1)
1720 evens: arr.filter(it % 2 == 0)
1721 }
1722 println(nums)
1723 assert nums.odds == [1, 3, 5]
1724 assert nums.evens == [2, 4]
1725}
1726
1727fn test_array_of_multi_map() {
1728 arr := [1, 3, 5]
1729 nums := Numbers{
1730 odds: arr.map(it + 2)
1731 evens: arr.map(it * 2)
1732 }
1733 println(nums)
1734 assert nums.odds == [3, 5, 7]
1735 assert nums.evens == [2, 6, 10]
1736}
1737
1738fn test_multi_fixed_array_with_default_init() {
1739 // TODO: multi-dimensional fixed array init in ARM64 backend
1740 // a := [3][3]int{init: [3]int{init: 10}}
1741 // assert a == [[10, 10, 10]!, [10, 10, 10]!, [10, 10, 10]!]!
1742}
1743
1744struct Abc {
1745mut:
1746 x i64
1747 y i64
1748 z i64
1749}
1750
1751fn test_clone_of_same_elem_size_array() {
1752 mut arr := []Abc{}
1753 arr << Abc{1, 2, 3}
1754 arr << Abc{2, 3, 4}
1755 arr2 := arr.clone()
1756 println(arr2)
1757 assert arr2 == [Abc{1, 2, 3}, Abc{2, 3, 4}]
1758}
1759
1760pub fn example[T](mut arr []T) []T {
1761 return arr.clone()
1762}
1763
1764fn test_generic_mutable_arrays() {
1765 // TODO: generic functions not working in ARM64 backend
1766 // mut arr := [1, 2, 3]
1767 // assert example(mut arr) == [1, 2, 3]
1768}
1769
1770struct Ok {}
1771
1772fn test_inline_array_element_access() {
1773 println([Ok{}][0])
1774 a1 := [Ok{}][0]
1775 assert a1 == Ok{}
1776
1777 println([1][0])
1778 a2 := [1][0]
1779 assert a2 == 1
1780}
1781
1782//
1783
1784fn f(x int, y int) []int {
1785 return [x, y]
1786}
1787
1788fn test_2d_array_init_with_it() {
1789 // TODO: 2D array init with index expression in ARM64 backend
1790 // a := [][]int{len: 6, init: f(index, 2 * index)}
1791 // assert a == [[0, 0], [1, 2], [2, 4], [3, 6], [4, 8], [5, 10]]
1792}
1793
1794fn test_using_array_name_variable() {
1795 array := []int{len: 4, init: index}
1796 println(array)
1797 assert array == [0, 1, 2, 3]
1798}
1799
1800struct Data {
1801mut:
1802 sub_map map[int]int
1803}
1804
1805fn test_array_of_struct_with_map_field() {
1806 n := 3
1807 mut arr := []Data{len: n}
1808 for i, mut a in arr {
1809 arr[i].sub_map[i] = 1
1810 a.sub_map[i] += 1
1811 }
1812 println(arr)
1813 // Note: test_array_of_struct_with_map_field fails sporadically on windows with the default `-gc boehm_full_opt`,
1814 // but it *does not* with any other `-gc` setting. The compiler does not matter; tested with tcc, gcc, clang .
1815 // The failure is from: `assert arr[0].sub_map == { 0: 2 }`, and it seems to also depend on the previous dump() calls
1816 // in this test file. If all of them are commented, it succeeds.
1817 // Tested with: rm vlib/builtin/array_test ; xtime v -keepc vlib/builtin/array_test.v ; for((i=0;i<100;i++)); do echo ">>>>>>>>>>>>>>>>>>>>>>>> $i"; ./vlib/builtin/array_test || break ; echo "done with $i"; done
1818 // executed in a git bash shell. It usually fails after the first 3-5 iterations.
1819 assert arr[0].sub_map == {
1820 0: 2
1821 }
1822 assert arr[1].sub_map == {
1823 1: 2
1824 }
1825 assert arr[2].sub_map == {
1826 2: 2
1827 }
1828}
1829
1830fn test_reset() {
1831 mut a := []int{len: 5, init: index * 10}
1832 assert a == [0, 10, 20, 30, 40]
1833 unsafe { a.reset() }
1834 assert a == [0, 0, 0, 0, 0]
1835
1836 mut b := []f64{len: 5, init: f64(index) / 10.0}
1837 assert b == [0.0, 0.1, 0.2, 0.3, 0.4]
1838 unsafe { b.reset() }
1839 assert b == [0.0, 0.0, 0.0, 0.0, 0.0]
1840
1841 // TODO: string array init with index.str() in ARM64 backend
1842 // mut s := []string{len: 5, init: index.str()}
1843 // assert s == ['0', '1', '2', '3', '4']
1844}
1845
1846fn test_index_of_ints() {
1847 ia := [1, 2, 3]
1848 ii := ia.index(2)
1849 dump(ii)
1850 assert ii == 1
1851}
1852
1853fn test_index_of_strings() {
1854 sa := ['a', 'b', 'c']
1855 si := sa.index('b')
1856 dump(si)
1857 assert si == 1
1858}
1859
1860fn test_index_of_voidptrs() {
1861 pa := [voidptr(123), voidptr(45), voidptr(99)]
1862 pi := pa.index(voidptr(45))
1863 dump(pi)
1864 assert pi == 1
1865}
1866
1867fn a() {}
1868
1869fn b() {}
1870
1871fn c() {}
1872
1873fn test_index_of_fns() {
1874 fa := [a, b, c]
1875 fi := fa.index(b)
1876 dump(fi)
1877 assert fi == 1
1878}
1879
1880fn test_sorted_immutable_original_should_not_change() {
1881 a := ['hi', '1', '5', '3']
1882 b := a.sorted()
1883 assert a == ['hi', '1', '5', '3']
1884 assert b == ['1', '3', '5', 'hi']
1885}
1886
1887fn test_sorted_mutable_original_should_not_change() {
1888 mut a := ['hi', '1', '5', '3']
1889 b := a.sorted()
1890 assert a == ['hi', '1', '5', '3']
1891 assert b == ['1', '3', '5', 'hi']
1892}
1893
1894fn test_sorted_reversed() {
1895 aa := ['hi', '1', '5', '3']
1896 bb := aa.sorted(a > b)
1897 assert aa == ['hi', '1', '5', '3']
1898 assert bb == ['hi', '5', '3', '1']
1899}
1900
1901fn test_sorted_by_len() {
1902 a := ['hi', 'abc', 'a', 'zzzzz']
1903 c := a.sorted(a.len < b.len)
1904 assert c == ['a', 'hi', 'abc', 'zzzzz']
1905}
1906
1907fn test_sorted_can_be_called_on_an_array_literals() {
1908 b := [5, 1, 9].sorted()
1909 assert b == [1, 5, 9]
1910 assert [5.0, 1.2, 9.4].sorted() == [1.2, 5.0, 9.4]
1911 assert ['a', '00', 'z', 'dd', 'xyz'].sorted(a > b) == ['z', 'xyz', 'dd', 'a', '00']
1912 assert ['a', '00', 'zzzzz', 'dddd', 'xyz'].sorted(a.len > b.len) == ['zzzzz', 'dddd', 'xyz',
1913 '00', 'a']
1914 assert ['a', '00', 'zzzzz', 'dddd', 'xyz'].sorted(a.len < b.len) == ['a', '00', 'xyz', 'dddd',
1915 'zzzzz']
1916}
1917
1918fn iarr() []int {
1919 return [5, 1, 9, 1, 2]
1920}
1921
1922fn test_sorted_can_be_called_on_the_result_of_a_fn() {
1923 assert iarr().sorted() == [1, 1, 2, 5, 9]
1924 assert iarr().sorted(a > b) == [9, 5, 2, 1, 1]
1925}
1926
1927fn test_sorting_2d_arrays() {
1928 assert [[1, 2], [3, 4, 5], [2]].sorted(a.len > b.len) == [
1929 [3, 4, 5],
1930 [1, 2],
1931 [2],
1932 ]
1933 assert [[1, 2], [3, 4, 5], [2]].sorted(a.len < b.len) == [
1934 [2],
1935 [1, 2],
1936 [3, 4, 5],
1937 ]
1938 // TODO: sorted with element indexing in ARM64 backend
1939 // assert unsafe { [[1, 2], [3, 4, 5], [2]].sorted(a[0] > b[0]) } == [
1940 // [3, 4, 5],
1941 // [2],
1942 // [1, 2],
1943 // ]
1944 // assert [[1, 2], [3, 4, 5], [2]].sorted( a.reduce(sum) > b.reduce(sum) ) == ... // TODO
1945}
1946
1947fn test_sorting_3d_arrays() {
1948 assert [[][]int{}, [[2, 22], [2]], [[3, 33], [3333], [33, 34, 35]],
1949 [[444]]].sorted(a.len > b.len) == [[[3, 33], [3333], [33, 34, 35]],
1950 [[2, 22], [2]], [[444]], [][]int{}]
1951}
1952
1953fn test_sorted_with_compare() {
1954 aa := ['hi', '1', '5', '3']
1955 bb := aa.sorted_with_compare(fn (a &string, b &string) int {
1956 if a < b {
1957 return -1
1958 }
1959 if a > b {
1960 return 1
1961 }
1962 return 0
1963 })
1964 assert aa == ['hi', '1', '5', '3'], 'aa should stay unmodified'
1965 assert bb == ['1', '3', '5', 'hi'], 'bb should be sorted, according to the custom comparison callback fn'
1966}
1967
1968fn cmp_2d_int_arrays_by_first_item(a &[]int, b &[]int) int {
1969 if a[0] < b[0] {
1970 return -1
1971 }
1972 if a[0] > b[0] {
1973 return 1
1974 }
1975 return 0
1976}
1977
1978struct SortPageObject {
1979 key []u8
1980}
1981
1982fn compare_page_object_keys_asc(a &SortPageObject, b &SortPageObject) int {
1983 return a.key[0] - b.key[0]
1984}
1985
1986fn compare_page_object_keys_desc(a &SortPageObject, b &SortPageObject) int {
1987 return b.key[0] - a.key[0]
1988}
1989
1990fn test_sorted_with_compare_2d_array() {
1991 aa := [[2], [1]]
1992 bb := aa.sorted_with_compare(cmp_2d_int_arrays_by_first_item)
1993 assert aa == [[2], [1]]
1994 assert bb == [[1], [2]]
1995 mut cc := aa.clone()
1996 cc.sort_with_compare(cmp_2d_int_arrays_by_first_item)
1997 assert cc == [[1], [2]]
1998}
1999
2000fn test_sort_with_compare_small_unsigned_difference() {
2001 a := SortPageObject{
2002 key: 'A'.bytes()
2003 }
2004 b := SortPageObject{
2005 key: 'B'.bytes()
2006 }
2007 c := SortPageObject{
2008 key: 'C'.bytes()
2009 }
2010
2011 mut objects1 := [b, a]
2012 objects1.sort_with_compare(compare_page_object_keys_asc)
2013 assert objects1.map(it.key.bytestr()) == ['A', 'B']
2014
2015 mut objects2 := [a, b]
2016 objects2.sort_with_compare(compare_page_object_keys_asc)
2017 assert objects2.map(it.key.bytestr()) == ['A', 'B']
2018
2019 mut objects3 := [a, b, c]
2020 objects3.sort_with_compare(compare_page_object_keys_asc)
2021 assert objects3.map(it.key.bytestr()) == ['A', 'B', 'C']
2022
2023 mut objects4 := [a, b, c]
2024 objects4.sort_with_compare(compare_page_object_keys_desc)
2025 assert objects4.map(it.key.bytestr()) == ['C', 'B', 'A']
2026}
2027