diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
commit | f6ad4dcef54c5ce997a4bad5a6d86de229015700 (patch) | |
tree | 7cfa4e31ace5c2bd95c72b154d15af494b2bcbef /test/range4.go | |
parent | Initial commit. (diff) | |
download | golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.tar.xz golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.zip |
Adding upstream version 1.22.1.upstream/1.22.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/range4.go')
-rw-r--r-- | test/range4.go | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/test/range4.go b/test/range4.go new file mode 100644 index 0000000..0b051f6 --- /dev/null +++ b/test/range4.go @@ -0,0 +1,351 @@ +// run -goexperiment rangefunc + +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Test the 'for range' construct ranging over functions. + +package main + +var gj int + +func yield4x(yield func() bool) { + _ = yield() && yield() && yield() && yield() +} + +func yield4(yield func(int) bool) { + _ = yield(1) && yield(2) && yield(3) && yield(4) +} + +func yield3(yield func(int) bool) { + _ = yield(1) && yield(2) && yield(3) +} + +func yield2(yield func(int) bool) { + _ = yield(1) && yield(2) +} + +func testfunc0() { + j := 0 + for range yield4x { + j++ + } + if j != 4 { + println("wrong count ranging over yield4x:", j) + panic("testfunc0") + } + + j = 0 + for _ = range yield4 { + j++ + } + if j != 4 { + println("wrong count ranging over yield4:", j) + panic("testfunc0") + } +} + +func testfunc1() { + bad := false + j := 1 + for i := range yield4 { + if i != j { + println("range var", i, "want", j) + bad = true + } + j++ + } + if j != 5 { + println("wrong count ranging over f:", j) + bad = true + } + if bad { + panic("testfunc1") + } +} + +func testfunc2() { + bad := false + j := 1 + var i int + for i = range yield4 { + if i != j { + println("range var", i, "want", j) + bad = true + } + j++ + } + if j != 5 { + println("wrong count ranging over f:", j) + bad = true + } + if i != 4 { + println("wrong final i ranging over f:", i) + bad = true + } + if bad { + panic("testfunc2") + } +} + +func testfunc3() { + bad := false + j := 1 + var i int + for i = range yield4 { + if i != j { + println("range var", i, "want", j) + bad = true + } + j++ + if i == 2 { + break + } + continue + } + if j != 3 { + println("wrong count ranging over f:", j) + bad = true + } + if i != 2 { + println("wrong final i ranging over f:", i) + bad = true + } + if bad { + panic("testfunc3") + } +} + +func testfunc4() { + bad := false + j := 1 + var i int + func() { + for i = range yield4 { + if i != j { + println("range var", i, "want", j) + bad = true + } + j++ + if i == 2 { + return + } + } + }() + if j != 3 { + println("wrong count ranging over f:", j) + bad = true + } + if i != 2 { + println("wrong final i ranging over f:", i) + bad = true + } + if bad { + panic("testfunc3") + } +} + +func func5() (int, int) { + for i := range yield4 { + return 10, i + } + panic("still here") +} + +func testfunc5() { + x, y := func5() + if x != 10 || y != 1 { + println("wrong results", x, y, "want", 10, 1) + panic("testfunc5") + } +} + +func func6() (z, w int) { + for i := range yield4 { + z = 10 + w = i + return + } + panic("still here") +} + +func testfunc6() { + x, y := func6() + if x != 10 || y != 1 { + println("wrong results", x, y, "want", 10, 1) + panic("testfunc6") + } +} + +var saved []int + +func save(x int) { + saved = append(saved, x) +} + +func printslice(s []int) { + print("[") + for i, x := range s { + if i > 0 { + print(", ") + } + print(x) + } + print("]") +} + +func eqslice(s, t []int) bool { + if len(s) != len(t) { + return false + } + for i, x := range s { + if x != t[i] { + return false + } + } + return true +} + +func func7() { + defer save(-1) + for i := range yield4 { + defer save(i) + } + defer save(5) +} + +func checkslice(name string, saved, want []int) { + if !eqslice(saved, want) { + print("wrong results ") + printslice(saved) + print(" want ") + printslice(want) + print("\n") + panic(name) + } +} + +func testfunc7() { + saved = nil + func7() + want := []int{5, 4, 3, 2, 1, -1} + checkslice("testfunc7", saved, want) +} + +func func8() { + defer save(-1) + for i := range yield2 { + for j := range yield3 { + defer save(i*10 + j) + } + defer save(i) + } + defer save(-2) + for i := range yield4 { + defer save(i) + } + defer save(-3) +} + +func testfunc8() { + saved = nil + func8() + want := []int{-3, 4, 3, 2, 1, -2, 2, 23, 22, 21, 1, 13, 12, 11, -1} + checkslice("testfunc8", saved, want) +} + +func func9() { + n := 0 + for _ = range yield2 { + for _ = range yield3 { + n++ + defer save(n) + } + } +} + +func testfunc9() { + saved = nil + func9() + want := []int{6, 5, 4, 3, 2, 1} + checkslice("testfunc9", saved, want) +} + +// test that range evaluates the index and value expressions +// exactly once per iteration. + +var ncalls = 0 + +func getvar(p *int) *int { + ncalls++ + return p +} + +func iter2(list ...int) func(func(int, int) bool) { + return func(yield func(int, int) bool) { + for i, x := range list { + if !yield(i, x) { + return + } + } + } +} + +func testcalls() { + var i, v int + ncalls = 0 + si := 0 + sv := 0 + for *getvar(&i), *getvar(&v) = range iter2(1, 2) { + si += i + sv += v + } + if ncalls != 4 { + println("wrong number of calls:", ncalls, "!= 4") + panic("fail") + } + if si != 1 || sv != 3 { + println("wrong sum in testcalls", si, sv) + panic("fail") + } +} + +type iter3YieldFunc func(int, int) bool + +func iter3(list ...int) func(iter3YieldFunc) { + return func(yield iter3YieldFunc) { + for k, v := range list { + if !yield(k, v) { + return + } + } + } +} + +func testcalls1() { + ncalls := 0 + for k, v := range iter3(1, 2, 3) { + _, _ = k, v + ncalls++ + } + if ncalls != 3 { + println("wrong number of calls:", ncalls, "!= 3") + panic("fail") + } +} + +func main() { + testfunc0() + testfunc1() + testfunc2() + testfunc3() + testfunc4() + testfunc5() + testfunc6() + testfunc7() + testfunc8() + testfunc9() + testcalls() + testcalls1() +} |