blob: 91ccd6307a56de463ad6f5bd456fb644bf8f0d17 [file] [log] [blame]
Russ Cox54aa8352009-03-20 11:32:58 -07001// $G $D/$F.go && $L $F.$A && ./$A.out
2
3// Copyright 2009 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7package main
8
9// test range over channels
10
11func gen(c chan int, lo, hi int) {
12 for i := lo; i <= hi; i++ {
Rob Pike325cf8e2010-03-24 16:46:53 -070013 c <- i
Russ Cox54aa8352009-03-20 11:32:58 -070014 }
Rob Pike325cf8e2010-03-24 16:46:53 -070015 close(c)
Russ Cox54aa8352009-03-20 11:32:58 -070016}
17
18func seq(lo, hi int) chan int {
Rob Pike325cf8e2010-03-24 16:46:53 -070019 c := make(chan int)
20 go gen(c, lo, hi)
21 return c
Russ Cox54aa8352009-03-20 11:32:58 -070022}
23
24func testchan() {
Rob Pike325cf8e2010-03-24 16:46:53 -070025 s := ""
Russ Cox54aa8352009-03-20 11:32:58 -070026 for i := range seq('a', 'z') {
Rob Pike325cf8e2010-03-24 16:46:53 -070027 s += string(i)
Russ Cox54aa8352009-03-20 11:32:58 -070028 }
29 if s != "abcdefghijklmnopqrstuvwxyz" {
Rob Pike325cf8e2010-03-24 16:46:53 -070030 println("Wanted lowercase alphabet; got", s)
31 panic("fail")
Russ Cox54aa8352009-03-20 11:32:58 -070032 }
33}
34
Russ Cox81c3e8c2010-07-01 18:04:25 -070035// test that range over slice only evaluates
Russ Cox54aa8352009-03-20 11:32:58 -070036// the expression after "range" once.
37
Rob Pike325cf8e2010-03-24 16:46:53 -070038var nmake = 0
39
Russ Cox81c3e8c2010-07-01 18:04:25 -070040func makeslice() []int {
Rob Pike325cf8e2010-03-24 16:46:53 -070041 nmake++
42 return []int{1, 2, 3, 4, 5}
Russ Cox54aa8352009-03-20 11:32:58 -070043}
44
Russ Cox81c3e8c2010-07-01 18:04:25 -070045func testslice() {
46 s := 0
47 nmake = 0
48 for _, v := range makeslice() {
49 s += v
50 }
51 if nmake != 1 {
52 println("range called makeslice", nmake, "times")
53 panic("fail")
54 }
55 if s != 15 {
56 println("wrong sum ranging over makeslice")
57 panic("fail")
58 }
59}
60
61func testslice1() {
62 s := 0
63 nmake = 0
64 for i := range makeslice() {
65 s += i
66 }
67 if nmake != 1 {
68 println("range called makeslice", nmake, "times")
69 panic("fail")
70 }
71 if s != 10 {
72 println("wrong sum ranging over makeslice")
73 panic("fail")
74 }
75}
76
77// test that range over array only evaluates
78// the expression after "range" once.
79
80func makearray() [5]int {
81 nmake++
82 return [5]int{1, 2, 3, 4, 5}
83}
84
Russ Cox54aa8352009-03-20 11:32:58 -070085func testarray() {
Rob Pike325cf8e2010-03-24 16:46:53 -070086 s := 0
Russ Cox81c3e8c2010-07-01 18:04:25 -070087 nmake = 0
Russ Coxae54cf72009-09-15 12:42:24 -070088 for _, v := range makearray() {
Rob Pike325cf8e2010-03-24 16:46:53 -070089 s += v
Russ Cox54aa8352009-03-20 11:32:58 -070090 }
91 if nmake != 1 {
Rob Pike325cf8e2010-03-24 16:46:53 -070092 println("range called makearray", nmake, "times")
93 panic("fail")
Russ Cox54aa8352009-03-20 11:32:58 -070094 }
95 if s != 15 {
Rob Pike325cf8e2010-03-24 16:46:53 -070096 println("wrong sum ranging over makearray")
97 panic("fail")
Russ Cox54aa8352009-03-20 11:32:58 -070098 }
99}
100
Russ Cox81c3e8c2010-07-01 18:04:25 -0700101func testarray1() {
102 s := 0
103 nmake = 0
104 for i := range makearray() {
105 s += i
106 }
107 if nmake != 1 {
108 println("range called makearray", nmake, "times")
109 panic("fail")
110 }
111 if s != 10 {
112 println("wrong sum ranging over makearray")
113 panic("fail")
114 }
115}
116
117func makearrayptr() *[5]int {
118 nmake++
119 return &[5]int{1, 2, 3, 4, 5}
120}
121
122func testarrayptr() {
123 nmake = 0
124 x := len(makearrayptr())
125 if x != 5 || nmake != 1 {
126 println("len called makearrayptr", nmake, "times and got len", x)
127 panic("fail")
128 }
129 nmake = 0
130 x = cap(makearrayptr())
131 if x != 5 || nmake != 1 {
132 println("cap called makearrayptr", nmake, "times and got len", x)
133 panic("fail")
134 }
135 s := 0
136 nmake = 0
137 for _, v := range makearrayptr() {
138 s += v
139 }
140 if nmake != 1 {
141 println("range called makearrayptr", nmake, "times")
142 panic("fail")
143 }
144 if s != 15 {
145 println("wrong sum ranging over makearrayptr")
146 panic("fail")
147 }
148}
149
150func testarrayptr1() {
151 s := 0
152 nmake = 0
153 for i := range makearrayptr() {
154 s += i
155 }
156 if nmake != 1 {
157 println("range called makearrayptr", nmake, "times")
158 panic("fail")
159 }
160 if s != 10 {
161 println("wrong sum ranging over makearrayptr")
162 panic("fail")
163 }
164}
165
166// test that range over string only evaluates
167// the expression after "range" once.
168
169func makestring() string {
170 nmake++
171 return "abcd☺"
172}
173
174func teststring() {
175 s := 0
176 nmake = 0
177 for _, v := range makestring() {
178 s += v
179 }
180 if nmake != 1 {
181 println("range called makestring", nmake, "times")
182 panic("fail")
183 }
184 if s != 'a'+'b'+'c'+'d'+'☺' {
185 println("wrong sum ranging over makestring")
186 panic("fail")
187 }
188}
189
190func teststring1() {
191 s := 0
192 nmake = 0
193 for i := range makestring() {
194 s += i
195 }
196 if nmake != 1 {
197 println("range called makestring", nmake, "times")
198 panic("fail")
199 }
200 if s != 10 {
201 println("wrong sum ranging over makestring")
202 panic("fail")
203 }
204}
205
206// test that range over map only evaluates
207// the expression after "range" once.
208
209func makemap() map[int]int {
210 nmake++
211 return map[int]int{0:'a', 1:'b', 2:'c', 3:'d', 4:'☺'}
212}
213
214func testmap() {
215 s := 0
216 nmake = 0
217 for _, v := range makemap() {
218 s += v
219 }
220 if nmake != 1 {
221 println("range called makemap", nmake, "times")
222 panic("fail")
223 }
224 if s != 'a'+'b'+'c'+'d'+'☺' {
225 println("wrong sum ranging over makemap")
226 panic("fail")
227 }
228}
229
230func testmap1() {
231 s := 0
232 nmake = 0
233 for i := range makemap() {
234 s += i
235 }
236 if nmake != 1 {
237 println("range called makemap", nmake, "times")
238 panic("fail")
239 }
240 if s != 10 {
241 println("wrong sum ranging over makemap")
242 panic("fail")
243 }
244}
245
Ian Lance Taylorff68f962010-01-15 10:40:30 -0800246// test that range evaluates the index and value expressions
247// exactly once per iteration.
248
249var ncalls = 0
Rob Pike325cf8e2010-03-24 16:46:53 -0700250
Ian Lance Taylorff68f962010-01-15 10:40:30 -0800251func getvar(p *int) *int {
252 ncalls++
253 return p
254}
255
256func testcalls() {
257 var i, v int
258 si := 0
259 sv := 0
260 for *getvar(&i), *getvar(&v) = range [2]int{1, 2} {
261 si += i
262 sv += v
263 }
264 if ncalls != 4 {
Rob Pike325cf8e2010-03-24 16:46:53 -0700265 println("wrong number of calls:", ncalls, "!= 4")
266 panic("fail")
Ian Lance Taylorff68f962010-01-15 10:40:30 -0800267 }
268 if si != 1 || sv != 3 {
Rob Pike325cf8e2010-03-24 16:46:53 -0700269 println("wrong sum in testcalls", si, sv)
270 panic("fail")
Ian Lance Taylorff68f962010-01-15 10:40:30 -0800271 }
272
273 ncalls = 0
274 for *getvar(&i), *getvar(&v) = range [0]int{} {
Rob Pike325cf8e2010-03-24 16:46:53 -0700275 println("loop ran on empty array")
276 panic("fail")
Ian Lance Taylorff68f962010-01-15 10:40:30 -0800277 }
278 if ncalls != 0 {
Rob Pike325cf8e2010-03-24 16:46:53 -0700279 println("wrong number of calls:", ncalls, "!= 0")
280 panic("fail")
Ian Lance Taylorff68f962010-01-15 10:40:30 -0800281 }
282}
283
Russ Cox54aa8352009-03-20 11:32:58 -0700284func main() {
Rob Pike325cf8e2010-03-24 16:46:53 -0700285 testchan()
286 testarray()
Russ Cox81c3e8c2010-07-01 18:04:25 -0700287 testarray1()
288 testarrayptr()
289 testarrayptr1()
290 testslice()
291 testslice1()
292 teststring()
293 teststring1()
294 testmap()
295 testmap1()
Rob Pike325cf8e2010-03-24 16:46:53 -0700296 testcalls()
Russ Cox54aa8352009-03-20 11:32:58 -0700297}