]> Cypherpunks.ru repositories - gostls13.git/blob - test/map.go
gc, runtime: handle floating point map keys
[gostls13.git] / test / map.go
1 // $G $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
7 package main
8
9 import (
10         "fmt"
11         "math"
12         "strconv"
13 )
14
15 const count = 100
16
17 func P(a []string) string {
18         s := "{"
19         for i := 0; i < len(a); i++ {
20                 if i > 0 {
21                         s += ","
22                 }
23                 s += `"` + a[i] + `"`
24         }
25         s += "}"
26         return s
27 }
28
29 func main() {
30         // Test a map literal.
31         mlit := map[string]int{"0": 0, "1": 1, "2": 2, "3": 3, "4": 4}
32         for i := 0; i < len(mlit); i++ {
33                 s := string([]byte{byte(i) + '0'})
34                 if mlit[s] != i {
35                         fmt.Printf("mlit[%s] = %d\n", s, mlit[s])
36                 }
37         }
38
39         mib := make(map[int]bool)
40         mii := make(map[int]int)
41         mfi := make(map[float32]int)
42         mif := make(map[int]float32)
43         msi := make(map[string]int)
44         mis := make(map[int]string)
45         mss := make(map[string]string)
46         mspa := make(map[string][]string)
47         // BUG need an interface map both ways too
48
49         type T struct {
50                 i int64 // can't use string here; struct values are only compared at the top level
51                 f float32
52         }
53         mipT := make(map[int]*T)
54         mpTi := make(map[*T]int)
55         mit := make(map[int]T)
56         //      mti := make(map[T] int)
57
58         type M map[int]int
59         mipM := make(map[int]M)
60
61         var apT [2 * count]*T
62
63         for i := 0; i < count; i++ {
64                 s := strconv.Itoa(i)
65                 s10 := strconv.Itoa(i * 10)
66                 f := float32(i)
67                 t := T{int64(i), f}
68                 apT[i] = new(T)
69                 apT[i].i = int64(i)
70                 apT[i].f = f
71                 apT[2*i] = new(T) // need twice as many entries as we use, for the nonexistence check
72                 apT[2*i].i = int64(i)
73                 apT[2*i].f = f
74                 m := M{i: i + 1}
75                 mib[i] = (i != 0)
76                 mii[i] = 10 * i
77                 mfi[float32(i)] = 10 * i
78                 mif[i] = 10.0 * f
79                 mis[i] = s
80                 msi[s] = i
81                 mss[s] = s10
82                 mss[s] = s10
83                 as := make([]string, 2)
84                 as[0] = s10
85                 as[1] = s10
86                 mspa[s] = as
87                 mipT[i] = apT[i]
88                 mpTi[apT[i]] = i
89                 mipM[i] = m
90                 mit[i] = t
91                 //      mti[t] = i
92         }
93
94         // test len
95         if len(mib) != count {
96                 fmt.Printf("len(mib) = %d\n", len(mib))
97         }
98         if len(mii) != count {
99                 fmt.Printf("len(mii) = %d\n", len(mii))
100         }
101         if len(mfi) != count {
102                 fmt.Printf("len(mfi) = %d\n", len(mfi))
103         }
104         if len(mif) != count {
105                 fmt.Printf("len(mif) = %d\n", len(mif))
106         }
107         if len(msi) != count {
108                 fmt.Printf("len(msi) = %d\n", len(msi))
109         }
110         if len(mis) != count {
111                 fmt.Printf("len(mis) = %d\n", len(mis))
112         }
113         if len(mss) != count {
114                 fmt.Printf("len(mss) = %d\n", len(mss))
115         }
116         if len(mspa) != count {
117                 fmt.Printf("len(mspa) = %d\n", len(mspa))
118         }
119         if len(mipT) != count {
120                 fmt.Printf("len(mipT) = %d\n", len(mipT))
121         }
122         if len(mpTi) != count {
123                 fmt.Printf("len(mpTi) = %d\n", len(mpTi))
124         }
125         //      if len(mti) != count {
126         //              fmt.Printf("len(mti) = %d\n", len(mti))
127         //      }
128         if len(mipM) != count {
129                 fmt.Printf("len(mipM) = %d\n", len(mipM))
130         }
131         //      if len(mti) != count {
132         //              fmt.Printf("len(mti) = %d\n", len(mti))
133         //      }
134         if len(mit) != count {
135                 fmt.Printf("len(mit) = %d\n", len(mit))
136         }
137
138         // test construction directly
139         for i := 0; i < count; i++ {
140                 s := strconv.Itoa(i)
141                 s10 := strconv.Itoa(i * 10)
142                 f := float32(i)
143                 // BUG m := M(i, i+1)
144                 if mib[i] != (i != 0) {
145                         fmt.Printf("mib[%d] = %t\n", i, mib[i])
146                 }
147                 if mii[i] != 10*i {
148                         fmt.Printf("mii[%d] = %d\n", i, mii[i])
149                 }
150                 if mfi[f] != 10*i {
151                         fmt.Printf("mfi[%d] = %d\n", i, mfi[f])
152                 }
153                 if mif[i] != 10.0*f {
154                         fmt.Printf("mif[%d] = %g\n", i, mif[i])
155                 }
156                 if mis[i] != s {
157                         fmt.Printf("mis[%d] = %s\n", i, mis[i])
158                 }
159                 if msi[s] != i {
160                         fmt.Printf("msi[%s] = %d\n", s, msi[s])
161                 }
162                 if mss[s] != s10 {
163                         fmt.Printf("mss[%s] = %g\n", s, mss[s])
164                 }
165                 for j := 0; j < len(mspa[s]); j++ {
166                         if mspa[s][j] != s10 {
167                                 fmt.Printf("mspa[%s][%d] = %s\n", s, j, mspa[s][j])
168                         }
169                 }
170                 if mipT[i].i != int64(i) || mipT[i].f != f {
171                         fmt.Printf("mipT[%d] = %v\n", i, mipT[i])
172                 }
173                 if mpTi[apT[i]] != i {
174                         fmt.Printf("mpTi[apT[%d]] = %d\n", i, mpTi[apT[i]])
175                 }
176                 //      if(mti[t] != i) {
177                 //              fmt.Printf("mti[%s] = %s\n", s, mti[t])
178                 //      }
179                 if mipM[i][i] != i+1 {
180                         fmt.Printf("mipM[%d][%d] = %d\n", i, i, mipM[i][i])
181                 }
182                 //      if(mti[t] != i) {
183                 //              fmt.Printf("mti[%v] = %d\n", t, mti[t])
184                 //      }
185                 if mit[i].i != int64(i) || mit[i].f != f {
186                         fmt.Printf("mit[%d] = {%d %g}\n", i, mit[i].i, mit[i].f)
187                 }
188         }
189
190         // test existence with tuple check
191         // failed lookups yield a false value for the boolean.
192         for i := 0; i < count; i++ {
193                 s := strconv.Itoa(i)
194                 f := float32(i)
195                 {
196                         _, b := mib[i]
197                         if !b {
198                                 fmt.Printf("tuple existence decl: mib[%d]\n", i)
199                         }
200                         _, b = mib[i]
201                         if !b {
202                                 fmt.Printf("tuple existence assign: mib[%d]\n", i)
203                         }
204                 }
205                 {
206                         _, b := mii[i]
207                         if !b {
208                                 fmt.Printf("tuple existence decl: mii[%d]\n", i)
209                         }
210                         _, b = mii[i]
211                         if !b {
212                                 fmt.Printf("tuple existence assign: mii[%d]\n", i)
213                         }
214                 }
215                 {
216                         _, b := mfi[f]
217                         if !b {
218                                 fmt.Printf("tuple existence decl: mfi[%d]\n", i)
219                         }
220                         _, b = mfi[f]
221                         if !b {
222                                 fmt.Printf("tuple existence assign: mfi[%d]\n", i)
223                         }
224                 }
225                 {
226                         _, b := mif[i]
227                         if !b {
228                                 fmt.Printf("tuple existence decl: mif[%d]\n", i)
229                         }
230                         _, b = mif[i]
231                         if !b {
232                                 fmt.Printf("tuple existence assign: mif[%d]\n", i)
233                         }
234                 }
235                 {
236                         _, b := mis[i]
237                         if !b {
238                                 fmt.Printf("tuple existence decl: mis[%d]\n", i)
239                         }
240                         _, b = mis[i]
241                         if !b {
242                                 fmt.Printf("tuple existence assign: mis[%d]\n", i)
243                         }
244                 }
245                 {
246                         _, b := msi[s]
247                         if !b {
248                                 fmt.Printf("tuple existence decl: msi[%d]\n", i)
249                         }
250                         _, b = msi[s]
251                         if !b {
252                                 fmt.Printf("tuple existence assign: msi[%d]\n", i)
253                         }
254                 }
255                 {
256                         _, b := mss[s]
257                         if !b {
258                                 fmt.Printf("tuple existence decl: mss[%d]\n", i)
259                         }
260                         _, b = mss[s]
261                         if !b {
262                                 fmt.Printf("tuple existence assign: mss[%d]\n", i)
263                         }
264                 }
265                 {
266                         _, b := mspa[s]
267                         if !b {
268                                 fmt.Printf("tuple existence decl: mspa[%d]\n", i)
269                         }
270                         _, b = mspa[s]
271                         if !b {
272                                 fmt.Printf("tuple existence assign: mspa[%d]\n", i)
273                         }
274                 }
275                 {
276                         _, b := mipT[i]
277                         if !b {
278                                 fmt.Printf("tuple existence decl: mipT[%d]\n", i)
279                         }
280                         _, b = mipT[i]
281                         if !b {
282                                 fmt.Printf("tuple existence assign: mipT[%d]\n", i)
283                         }
284                 }
285                 {
286                         _, b := mpTi[apT[i]]
287                         if !b {
288                                 fmt.Printf("tuple existence decl: mpTi[apT[%d]]\n", i)
289                         }
290                         _, b = mpTi[apT[i]]
291                         if !b {
292                                 fmt.Printf("tuple existence assign: mpTi[apT[%d]]\n", i)
293                         }
294                 }
295                 {
296                         _, b := mipM[i]
297                         if !b {
298                                 fmt.Printf("tuple existence decl: mipM[%d]\n", i)
299                         }
300                         _, b = mipM[i]
301                         if !b {
302                                 fmt.Printf("tuple existence assign: mipM[%d]\n", i)
303                         }
304                 }
305                 {
306                         _, b := mit[i]
307                         if !b {
308                                 fmt.Printf("tuple existence decl: mit[%d]\n", i)
309                         }
310                         _, b = mit[i]
311                         if !b {
312                                 fmt.Printf("tuple existence assign: mit[%d]\n", i)
313                         }
314                 }
315                 //              {
316                 //                      _, b := mti[t]
317                 //                      if !b {
318                 //                              fmt.Printf("tuple existence decl: mti[%d]\n", i)
319                 //                      }
320                 //                      _, b = mti[t]
321                 //                      if !b {
322                 //                              fmt.Printf("tuple existence assign: mti[%d]\n", i)
323                 //                      }
324                 //              }
325         }
326
327         // test nonexistence with tuple check
328         // failed lookups yield a false value for the boolean.
329         for i := count; i < 2*count; i++ {
330                 s := strconv.Itoa(i)
331                 f := float32(i)
332                 {
333                         _, b := mib[i]
334                         if b {
335                                 fmt.Printf("tuple nonexistence decl: mib[%d]", i)
336                         }
337                         _, b = mib[i]
338                         if b {
339                                 fmt.Printf("tuple nonexistence assign: mib[%d]", i)
340                         }
341                 }
342                 {
343                         _, b := mii[i]
344                         if b {
345                                 fmt.Printf("tuple nonexistence decl: mii[%d]", i)
346                         }
347                         _, b = mii[i]
348                         if b {
349                                 fmt.Printf("tuple nonexistence assign: mii[%d]", i)
350                         }
351                 }
352                 {
353                         _, b := mfi[f]
354                         if b {
355                                 fmt.Printf("tuple nonexistence decl: mfi[%d]", i)
356                         }
357                         _, b = mfi[f]
358                         if b {
359                                 fmt.Printf("tuple nonexistence assign: mfi[%d]", i)
360                         }
361                 }
362                 {
363                         _, b := mif[i]
364                         if b {
365                                 fmt.Printf("tuple nonexistence decl: mif[%d]", i)
366                         }
367                         _, b = mif[i]
368                         if b {
369                                 fmt.Printf("tuple nonexistence assign: mif[%d]", i)
370                         }
371                 }
372                 {
373                         _, b := mis[i]
374                         if b {
375                                 fmt.Printf("tuple nonexistence decl: mis[%d]", i)
376                         }
377                         _, b = mis[i]
378                         if b {
379                                 fmt.Printf("tuple nonexistence assign: mis[%d]", i)
380                         }
381                 }
382                 {
383                         _, b := msi[s]
384                         if b {
385                                 fmt.Printf("tuple nonexistence decl: msi[%d]", i)
386                         }
387                         _, b = msi[s]
388                         if b {
389                                 fmt.Printf("tuple nonexistence assign: msi[%d]", i)
390                         }
391                 }
392                 {
393                         _, b := mss[s]
394                         if b {
395                                 fmt.Printf("tuple nonexistence decl: mss[%d]", i)
396                         }
397                         _, b = mss[s]
398                         if b {
399                                 fmt.Printf("tuple nonexistence assign: mss[%d]", i)
400                         }
401                 }
402                 {
403                         _, b := mspa[s]
404                         if b {
405                                 fmt.Printf("tuple nonexistence decl: mspa[%d]", i)
406                         }
407                         _, b = mspa[s]
408                         if b {
409                                 fmt.Printf("tuple nonexistence assign: mspa[%d]", i)
410                         }
411                 }
412                 {
413                         _, b := mipT[i]
414                         if b {
415                                 fmt.Printf("tuple nonexistence decl: mipT[%d]", i)
416                         }
417                         _, b = mipT[i]
418                         if b {
419                                 fmt.Printf("tuple nonexistence assign: mipT[%d]", i)
420                         }
421                 }
422                 {
423                         _, b := mpTi[apT[i]]
424                         if b {
425                                 fmt.Printf("tuple nonexistence decl: mpTi[apt[%d]]", i)
426                         }
427                         _, b = mpTi[apT[i]]
428                         if b {
429                                 fmt.Printf("tuple nonexistence assign: mpTi[apT[%d]]", i)
430                         }
431                 }
432                 {
433                         _, b := mipM[i]
434                         if b {
435                                 fmt.Printf("tuple nonexistence decl: mipM[%d]", i)
436                         }
437                         _, b = mipM[i]
438                         if b {
439                                 fmt.Printf("tuple nonexistence assign: mipM[%d]", i)
440                         }
441                 }
442                 //              {
443                 //                      _, b := mti[t]
444                 //                      if b {
445                 //                              fmt.Printf("tuple nonexistence decl: mti[%d]", i)
446                 //                      }
447                 //                      _, b = mti[t]
448                 //                      if b {
449                 //                              fmt.Printf("tuple nonexistence assign: mti[%d]", i)
450                 //                      }
451                 //              }
452                 {
453                         _, b := mit[i]
454                         if b {
455                                 fmt.Printf("tuple nonexistence decl: mit[%d]", i)
456                         }
457                         _, b = mit[i]
458                         if b {
459                                 fmt.Printf("tuple nonexistence assign: mit[%d]", i)
460                         }
461                 }
462         }
463
464         // tests for structured map element updates
465         for i := 0; i < count; i++ {
466                 s := strconv.Itoa(i)
467                 mspa[s][i%2] = "deleted"
468                 if mspa[s][i%2] != "deleted" {
469                         fmt.Printf("update mspa[%s][%d] = %s\n", s, i%2, mspa[s][i%2])
470                 }
471
472                 mipT[i].i += 1
473                 if mipT[i].i != int64(i)+1 {
474                         fmt.Printf("update mipT[%d].i = %d\n", i, mipT[i].i)
475                 }
476                 mipT[i].f = float32(i + 1)
477                 if mipT[i].f != float32(i+1) {
478                         fmt.Printf("update mipT[%d].f = %g\n", i, mipT[i].f)
479                 }
480
481                 mipM[i][i]++
482                 if mipM[i][i] != (i+1)+1 {
483                         fmt.Printf("update mipM[%d][%d] = %i\n", i, i, mipM[i][i])
484                 }
485         }
486
487         // test range on nil map
488         var mnil map[string]int
489         for _, _ = range mnil {
490                 panic("range mnil")
491         }
492
493         testfloat()
494 }
495
496 func testfloat() {
497         // Test floating point numbers in maps.
498         // Two map keys refer to the same entry if the keys are ==.
499         // The special cases, then, are that +0 == -0 and that NaN != NaN.
500
501         {
502                 var (
503                         pz   = float32(0)
504                         nz   = math.Float32frombits(1 << 31)
505                         nana = float32(math.NaN())
506                         nanb = math.Float32frombits(math.Float32bits(nana) ^ 2)
507                 )
508
509                 m := map[float32]string{
510                         pz:   "+0",
511                         nana: "NaN",
512                         nanb: "NaN",
513                 }
514                 if m[pz] != "+0" {
515                         fmt.Println("float32 map cannot read back m[+0]:", m[pz])
516                 }
517                 if m[nz] != "+0" {
518                         fmt.Println("float32 map does not treat", pz, "and", nz, "as equal for read")
519                         fmt.Println("float32 map does not treat -0 and +0 as equal for read")
520                 }
521                 m[nz] = "-0"
522                 if m[pz] != "-0" {
523                         fmt.Println("float32 map does not treat -0 and +0 as equal for write")
524                 }
525                 if _, ok := m[nana]; ok {
526                         fmt.Println("float32 map allows NaN lookup (a)")
527                 }
528                 if _, ok := m[nanb]; ok {
529                         fmt.Println("float32 map allows NaN lookup (b)")
530                 }
531                 if len(m) != 3 {
532                         fmt.Println("float32 map should have 3 entries:", m)
533                 }
534                 m[nana] = "NaN"
535                 m[nanb] = "NaN"
536                 if len(m) != 5 {
537                         fmt.Println("float32 map should have 5 entries:", m)
538                 }
539         }
540
541         {
542                 var (
543                         pz   = float64(0)
544                         nz   = math.Float64frombits(1 << 63)
545                         nana = float64(math.NaN())
546                         nanb = math.Float64frombits(math.Float64bits(nana) ^ 2)
547                 )
548
549                 m := map[float64]string{
550                         pz:   "+0",
551                         nana: "NaN",
552                         nanb: "NaN",
553                 }
554                 if m[nz] != "+0" {
555                         fmt.Println("float64 map does not treat -0 and +0 as equal for read")
556                 }
557                 m[nz] = "-0"
558                 if m[pz] != "-0" {
559                         fmt.Println("float64 map does not treat -0 and +0 as equal for write")
560                 }
561                 if _, ok := m[nana]; ok {
562                         fmt.Println("float64 map allows NaN lookup (a)")
563                 }
564                 if _, ok := m[nanb]; ok {
565                         fmt.Println("float64 map allows NaN lookup (b)")
566                 }
567                 if len(m) != 3 {
568                         fmt.Println("float64 map should have 3 entries:", m)
569                 }
570                 m[nana] = "NaN"
571                 m[nanb] = "NaN"
572                 if len(m) != 5 {
573                         fmt.Println("float64 map should have 5 entries:", m)
574                 }
575         }
576
577         {
578                 var (
579                         pz   = complex64(0)
580                         nz   = complex(0, math.Float32frombits(1<<31))
581                         nana = complex(5, float32(math.NaN()))
582                         nanb = complex(5, math.Float32frombits(math.Float32bits(float32(math.NaN()))^2))
583                 )
584
585                 m := map[complex64]string{
586                         pz:   "+0",
587                         nana: "NaN",
588                         nanb: "NaN",
589                 }
590                 if m[nz] != "+0" {
591                         fmt.Println("complex64 map does not treat -0 and +0 as equal for read")
592                 }
593                 m[nz] = "-0"
594                 if m[pz] != "-0" {
595                         fmt.Println("complex64 map does not treat -0 and +0 as equal for write")
596                 }
597                 if _, ok := m[nana]; ok {
598                         fmt.Println("complex64 map allows NaN lookup (a)")
599                 }
600                 if _, ok := m[nanb]; ok {
601                         fmt.Println("complex64 map allows NaN lookup (b)")
602                 }
603                 if len(m) != 3 {
604                         fmt.Println("complex64 map should have 3 entries:", m)
605                 }
606                 m[nana] = "NaN"
607                 m[nanb] = "NaN"
608                 if len(m) != 5 {
609                         fmt.Println("complex64 map should have 5 entries:", m)
610                 }
611         }
612
613         {
614                 var (
615                         pz   = complex128(0)
616                         nz   = complex(0, math.Float64frombits(1<<63))
617                         nana = complex(5, float64(math.NaN()))
618                         nanb = complex(5, math.Float64frombits(math.Float64bits(float64(math.NaN()))^2))
619                 )
620
621                 m := map[complex128]string{
622                         pz:   "+0",
623                         nana: "NaN",
624                         nanb: "NaN",
625                 }
626                 if m[nz] != "+0" {
627                         fmt.Println("complex128 map does not treat -0 and +0 as equal for read")
628                 }
629                 m[nz] = "-0"
630                 if m[pz] != "-0" {
631                         fmt.Println("complex128 map does not treat -0 and +0 as equal for write")
632                 }
633                 if _, ok := m[nana]; ok {
634                         fmt.Println("complex128 map allows NaN lookup (a)")
635                 }
636                 if _, ok := m[nanb]; ok {
637                         fmt.Println("complex128 map allows NaN lookup (b)")
638                 }
639                 if len(m) != 3 {
640                         fmt.Println("complex128 map should have 3 entries:", m)
641                 }
642                 m[nana] = "NaN"
643                 m[nanb] = "NaN"
644                 if len(m) != 5 {
645                         fmt.Println("complex128 map should have 5 entries:", m)
646                 }
647         }
648 }