1
2
3
4
5 package field
6
7 import (
8 "testing"
9 "testing/quick"
10 )
11
12 func checkAliasingOneArg(f func(v, x *Element) *Element) func(v, x Element) bool {
13 return func(v, x Element) bool {
14 x1, v1 := x, x
15
16
17 if out := f(&v, &x); out != &v && isInBounds(out) {
18 return false
19 }
20
21
22 if out := f(&v1, &v1); out != &v1 || v1 != v {
23 return false
24 }
25
26
27 return x == x1
28 }
29 }
30
31 func checkAliasingTwoArgs(f func(v, x, y *Element) *Element) func(v, x, y Element) bool {
32 return func(v, x, y Element) bool {
33 x1, y1, v1 := x, y, Element{}
34
35
36 if out := f(&v, &x, &y); out != &v && isInBounds(out) {
37 return false
38 }
39
40
41 v1 = x
42 if out := f(&v1, &v1, &y); out != &v1 || v1 != v {
43 return false
44 }
45
46 v1 = y
47 if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
48 return false
49 }
50
51
52 if out := f(&v, &x, &x); out != &v {
53 return false
54 }
55
56
57 v1 = x
58 if out := f(&v1, &v1, &x); out != &v1 || v1 != v {
59 return false
60 }
61
62 v1 = x
63 if out := f(&v1, &x, &v1); out != &v1 || v1 != v {
64 return false
65 }
66
67 v1 = x
68 if out := f(&v1, &v1, &v1); out != &v1 || v1 != v {
69 return false
70 }
71
72
73 return x == x1 && y == y1
74 }
75 }
76
77
78
79
80
81
82
83
84
85
86
87 func TestAliasing(t *testing.T) {
88 type target struct {
89 name string
90 oneArgF func(v, x *Element) *Element
91 twoArgsF func(v, x, y *Element) *Element
92 }
93 for _, tt := range []target{
94 {name: "Absolute", oneArgF: (*Element).Absolute},
95 {name: "Invert", oneArgF: (*Element).Invert},
96 {name: "Negate", oneArgF: (*Element).Negate},
97 {name: "Set", oneArgF: (*Element).Set},
98 {name: "Square", oneArgF: (*Element).Square},
99 {
100 name: "SquareN",
101 oneArgF: func(v, x *Element) *Element {
102 return v.SquareN(x, 10)
103 },
104 },
105 {name: "Pow22523", oneArgF: (*Element).Pow22523},
106 {
107 name: "Mult32",
108 oneArgF: func(v, x *Element) *Element {
109 return v.Mult32(x, 0xffffffff)
110 },
111 },
112 {name: "Multiply", twoArgsF: (*Element).Multiply},
113 {name: "Add", twoArgsF: (*Element).Add},
114 {name: "Subtract", twoArgsF: (*Element).Subtract},
115 {
116 name: "SqrtRatio",
117 twoArgsF: func(v, x, y *Element) *Element {
118 r, _ := v.SqrtRatio(x, y)
119 return r
120 },
121 },
122 {
123 name: "Select0",
124 twoArgsF: func(v, x, y *Element) *Element {
125 return v.Select(x, y, 0)
126 },
127 },
128 {
129 name: "Select1",
130 twoArgsF: func(v, x, y *Element) *Element {
131 return v.Select(x, y, 1)
132 },
133 },
134 } {
135 var err error
136 switch {
137 case tt.oneArgF != nil:
138 err = quick.Check(checkAliasingOneArg(tt.oneArgF), quickCheckConfig(256))
139 case tt.twoArgsF != nil:
140 err = quick.Check(checkAliasingTwoArgs(tt.twoArgsF), quickCheckConfig(256))
141 }
142 if err != nil {
143 t.Errorf("%v: %v", tt.name, err)
144 }
145 }
146 }
147
View as plain text