diff options
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/function/stdlib/number.go')
-rw-r--r-- | vendor/github.com/zclconf/go-cty/cty/function/stdlib/number.go | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/function/stdlib/number.go b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/number.go new file mode 100644 index 0000000..bd9b2e5 --- /dev/null +++ b/vendor/github.com/zclconf/go-cty/cty/function/stdlib/number.go | |||
@@ -0,0 +1,428 @@ | |||
1 | package stdlib | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "math/big" | ||
6 | |||
7 | "github.com/zclconf/go-cty/cty" | ||
8 | "github.com/zclconf/go-cty/cty/function" | ||
9 | ) | ||
10 | |||
11 | var AbsoluteFunc = function.New(&function.Spec{ | ||
12 | Params: []function.Parameter{ | ||
13 | { | ||
14 | Name: "num", | ||
15 | Type: cty.Number, | ||
16 | AllowDynamicType: true, | ||
17 | }, | ||
18 | }, | ||
19 | Type: function.StaticReturnType(cty.Number), | ||
20 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
21 | return args[0].Absolute(), nil | ||
22 | }, | ||
23 | }) | ||
24 | |||
25 | var AddFunc = function.New(&function.Spec{ | ||
26 | Params: []function.Parameter{ | ||
27 | { | ||
28 | Name: "a", | ||
29 | Type: cty.Number, | ||
30 | AllowDynamicType: true, | ||
31 | }, | ||
32 | { | ||
33 | Name: "b", | ||
34 | Type: cty.Number, | ||
35 | AllowDynamicType: true, | ||
36 | }, | ||
37 | }, | ||
38 | Type: function.StaticReturnType(cty.Number), | ||
39 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
40 | // big.Float.Add can panic if the input values are opposing infinities, | ||
41 | // so we must catch that here in order to remain within | ||
42 | // the cty Function abstraction. | ||
43 | defer func() { | ||
44 | if r := recover(); r != nil { | ||
45 | if _, ok := r.(big.ErrNaN); ok { | ||
46 | ret = cty.NilVal | ||
47 | err = fmt.Errorf("can't compute sum of opposing infinities") | ||
48 | } else { | ||
49 | // not a panic we recognize | ||
50 | panic(r) | ||
51 | } | ||
52 | } | ||
53 | }() | ||
54 | return args[0].Add(args[1]), nil | ||
55 | }, | ||
56 | }) | ||
57 | |||
58 | var SubtractFunc = function.New(&function.Spec{ | ||
59 | Params: []function.Parameter{ | ||
60 | { | ||
61 | Name: "a", | ||
62 | Type: cty.Number, | ||
63 | AllowDynamicType: true, | ||
64 | }, | ||
65 | { | ||
66 | Name: "b", | ||
67 | Type: cty.Number, | ||
68 | AllowDynamicType: true, | ||
69 | }, | ||
70 | }, | ||
71 | Type: function.StaticReturnType(cty.Number), | ||
72 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
73 | // big.Float.Sub can panic if the input values are infinities, | ||
74 | // so we must catch that here in order to remain within | ||
75 | // the cty Function abstraction. | ||
76 | defer func() { | ||
77 | if r := recover(); r != nil { | ||
78 | if _, ok := r.(big.ErrNaN); ok { | ||
79 | ret = cty.NilVal | ||
80 | err = fmt.Errorf("can't subtract infinity from itself") | ||
81 | } else { | ||
82 | // not a panic we recognize | ||
83 | panic(r) | ||
84 | } | ||
85 | } | ||
86 | }() | ||
87 | return args[0].Subtract(args[1]), nil | ||
88 | }, | ||
89 | }) | ||
90 | |||
91 | var MultiplyFunc = function.New(&function.Spec{ | ||
92 | Params: []function.Parameter{ | ||
93 | { | ||
94 | Name: "a", | ||
95 | Type: cty.Number, | ||
96 | AllowDynamicType: true, | ||
97 | }, | ||
98 | { | ||
99 | Name: "b", | ||
100 | Type: cty.Number, | ||
101 | AllowDynamicType: true, | ||
102 | }, | ||
103 | }, | ||
104 | Type: function.StaticReturnType(cty.Number), | ||
105 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
106 | // big.Float.Mul can panic if the input values are both zero or both | ||
107 | // infinity, so we must catch that here in order to remain within | ||
108 | // the cty Function abstraction. | ||
109 | defer func() { | ||
110 | if r := recover(); r != nil { | ||
111 | if _, ok := r.(big.ErrNaN); ok { | ||
112 | ret = cty.NilVal | ||
113 | err = fmt.Errorf("can't multiply zero by infinity") | ||
114 | } else { | ||
115 | // not a panic we recognize | ||
116 | panic(r) | ||
117 | } | ||
118 | } | ||
119 | }() | ||
120 | |||
121 | return args[0].Multiply(args[1]), nil | ||
122 | }, | ||
123 | }) | ||
124 | |||
125 | var DivideFunc = function.New(&function.Spec{ | ||
126 | Params: []function.Parameter{ | ||
127 | { | ||
128 | Name: "a", | ||
129 | Type: cty.Number, | ||
130 | AllowDynamicType: true, | ||
131 | }, | ||
132 | { | ||
133 | Name: "b", | ||
134 | Type: cty.Number, | ||
135 | AllowDynamicType: true, | ||
136 | }, | ||
137 | }, | ||
138 | Type: function.StaticReturnType(cty.Number), | ||
139 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
140 | // big.Float.Quo can panic if the input values are both zero or both | ||
141 | // infinity, so we must catch that here in order to remain within | ||
142 | // the cty Function abstraction. | ||
143 | defer func() { | ||
144 | if r := recover(); r != nil { | ||
145 | if _, ok := r.(big.ErrNaN); ok { | ||
146 | ret = cty.NilVal | ||
147 | err = fmt.Errorf("can't divide zero by zero or infinity by infinity") | ||
148 | } else { | ||
149 | // not a panic we recognize | ||
150 | panic(r) | ||
151 | } | ||
152 | } | ||
153 | }() | ||
154 | |||
155 | return args[0].Divide(args[1]), nil | ||
156 | }, | ||
157 | }) | ||
158 | |||
159 | var ModuloFunc = function.New(&function.Spec{ | ||
160 | Params: []function.Parameter{ | ||
161 | { | ||
162 | Name: "a", | ||
163 | Type: cty.Number, | ||
164 | AllowDynamicType: true, | ||
165 | }, | ||
166 | { | ||
167 | Name: "b", | ||
168 | Type: cty.Number, | ||
169 | AllowDynamicType: true, | ||
170 | }, | ||
171 | }, | ||
172 | Type: function.StaticReturnType(cty.Number), | ||
173 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
174 | // big.Float.Mul can panic if the input values are both zero or both | ||
175 | // infinity, so we must catch that here in order to remain within | ||
176 | // the cty Function abstraction. | ||
177 | defer func() { | ||
178 | if r := recover(); r != nil { | ||
179 | if _, ok := r.(big.ErrNaN); ok { | ||
180 | ret = cty.NilVal | ||
181 | err = fmt.Errorf("can't use modulo with zero and infinity") | ||
182 | } else { | ||
183 | // not a panic we recognize | ||
184 | panic(r) | ||
185 | } | ||
186 | } | ||
187 | }() | ||
188 | |||
189 | return args[0].Modulo(args[1]), nil | ||
190 | }, | ||
191 | }) | ||
192 | |||
193 | var GreaterThanFunc = function.New(&function.Spec{ | ||
194 | Params: []function.Parameter{ | ||
195 | { | ||
196 | Name: "a", | ||
197 | Type: cty.Number, | ||
198 | AllowDynamicType: true, | ||
199 | }, | ||
200 | { | ||
201 | Name: "b", | ||
202 | Type: cty.Number, | ||
203 | AllowDynamicType: true, | ||
204 | }, | ||
205 | }, | ||
206 | Type: function.StaticReturnType(cty.Bool), | ||
207 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
208 | return args[0].GreaterThan(args[1]), nil | ||
209 | }, | ||
210 | }) | ||
211 | |||
212 | var GreaterThanOrEqualToFunc = function.New(&function.Spec{ | ||
213 | Params: []function.Parameter{ | ||
214 | { | ||
215 | Name: "a", | ||
216 | Type: cty.Number, | ||
217 | AllowDynamicType: true, | ||
218 | }, | ||
219 | { | ||
220 | Name: "b", | ||
221 | Type: cty.Number, | ||
222 | AllowDynamicType: true, | ||
223 | }, | ||
224 | }, | ||
225 | Type: function.StaticReturnType(cty.Bool), | ||
226 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
227 | return args[0].GreaterThanOrEqualTo(args[1]), nil | ||
228 | }, | ||
229 | }) | ||
230 | |||
231 | var LessThanFunc = function.New(&function.Spec{ | ||
232 | Params: []function.Parameter{ | ||
233 | { | ||
234 | Name: "a", | ||
235 | Type: cty.Number, | ||
236 | AllowDynamicType: true, | ||
237 | }, | ||
238 | { | ||
239 | Name: "b", | ||
240 | Type: cty.Number, | ||
241 | AllowDynamicType: true, | ||
242 | }, | ||
243 | }, | ||
244 | Type: function.StaticReturnType(cty.Bool), | ||
245 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
246 | return args[0].LessThan(args[1]), nil | ||
247 | }, | ||
248 | }) | ||
249 | |||
250 | var LessThanOrEqualToFunc = function.New(&function.Spec{ | ||
251 | Params: []function.Parameter{ | ||
252 | { | ||
253 | Name: "a", | ||
254 | Type: cty.Number, | ||
255 | AllowDynamicType: true, | ||
256 | }, | ||
257 | { | ||
258 | Name: "b", | ||
259 | Type: cty.Number, | ||
260 | AllowDynamicType: true, | ||
261 | }, | ||
262 | }, | ||
263 | Type: function.StaticReturnType(cty.Bool), | ||
264 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
265 | return args[0].LessThanOrEqualTo(args[1]), nil | ||
266 | }, | ||
267 | }) | ||
268 | |||
269 | var NegateFunc = function.New(&function.Spec{ | ||
270 | Params: []function.Parameter{ | ||
271 | { | ||
272 | Name: "num", | ||
273 | Type: cty.Number, | ||
274 | AllowDynamicType: true, | ||
275 | }, | ||
276 | }, | ||
277 | Type: function.StaticReturnType(cty.Number), | ||
278 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
279 | return args[0].Negate(), nil | ||
280 | }, | ||
281 | }) | ||
282 | |||
283 | var MinFunc = function.New(&function.Spec{ | ||
284 | Params: []function.Parameter{}, | ||
285 | VarParam: &function.Parameter{ | ||
286 | Name: "numbers", | ||
287 | Type: cty.Number, | ||
288 | AllowDynamicType: true, | ||
289 | }, | ||
290 | Type: function.StaticReturnType(cty.Number), | ||
291 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
292 | if len(args) == 0 { | ||
293 | return cty.NilVal, fmt.Errorf("must pass at least one number") | ||
294 | } | ||
295 | |||
296 | min := cty.PositiveInfinity | ||
297 | for _, num := range args { | ||
298 | if num.LessThan(min).True() { | ||
299 | min = num | ||
300 | } | ||
301 | } | ||
302 | |||
303 | return min, nil | ||
304 | }, | ||
305 | }) | ||
306 | |||
307 | var MaxFunc = function.New(&function.Spec{ | ||
308 | Params: []function.Parameter{}, | ||
309 | VarParam: &function.Parameter{ | ||
310 | Name: "numbers", | ||
311 | Type: cty.Number, | ||
312 | AllowDynamicType: true, | ||
313 | }, | ||
314 | Type: function.StaticReturnType(cty.Number), | ||
315 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
316 | if len(args) == 0 { | ||
317 | return cty.NilVal, fmt.Errorf("must pass at least one number") | ||
318 | } | ||
319 | |||
320 | max := cty.NegativeInfinity | ||
321 | for _, num := range args { | ||
322 | if num.GreaterThan(max).True() { | ||
323 | max = num | ||
324 | } | ||
325 | } | ||
326 | |||
327 | return max, nil | ||
328 | }, | ||
329 | }) | ||
330 | |||
331 | var IntFunc = function.New(&function.Spec{ | ||
332 | Params: []function.Parameter{ | ||
333 | { | ||
334 | Name: "num", | ||
335 | Type: cty.Number, | ||
336 | AllowDynamicType: true, | ||
337 | }, | ||
338 | }, | ||
339 | Type: function.StaticReturnType(cty.Number), | ||
340 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
341 | bf := args[0].AsBigFloat() | ||
342 | if bf.IsInt() { | ||
343 | return args[0], nil | ||
344 | } | ||
345 | bi, _ := bf.Int(nil) | ||
346 | bf = (&big.Float{}).SetInt(bi) | ||
347 | return cty.NumberVal(bf), nil | ||
348 | }, | ||
349 | }) | ||
350 | |||
351 | // Absolute returns the magnitude of the given number, without its sign. | ||
352 | // That is, it turns negative values into positive values. | ||
353 | func Absolute(num cty.Value) (cty.Value, error) { | ||
354 | return AbsoluteFunc.Call([]cty.Value{num}) | ||
355 | } | ||
356 | |||
357 | // Add returns the sum of the two given numbers. | ||
358 | func Add(a cty.Value, b cty.Value) (cty.Value, error) { | ||
359 | return AddFunc.Call([]cty.Value{a, b}) | ||
360 | } | ||
361 | |||
362 | // Subtract returns the difference between the two given numbers. | ||
363 | func Subtract(a cty.Value, b cty.Value) (cty.Value, error) { | ||
364 | return SubtractFunc.Call([]cty.Value{a, b}) | ||
365 | } | ||
366 | |||
367 | // Multiply returns the product of the two given numbers. | ||
368 | func Multiply(a cty.Value, b cty.Value) (cty.Value, error) { | ||
369 | return MultiplyFunc.Call([]cty.Value{a, b}) | ||
370 | } | ||
371 | |||
372 | // Divide returns a divided by b, where both a and b are numbers. | ||
373 | func Divide(a cty.Value, b cty.Value) (cty.Value, error) { | ||
374 | return DivideFunc.Call([]cty.Value{a, b}) | ||
375 | } | ||
376 | |||
377 | // Negate returns the given number multipled by -1. | ||
378 | func Negate(num cty.Value) (cty.Value, error) { | ||
379 | return NegateFunc.Call([]cty.Value{num}) | ||
380 | } | ||
381 | |||
382 | // LessThan returns true if a is less than b. | ||
383 | func LessThan(a cty.Value, b cty.Value) (cty.Value, error) { | ||
384 | return LessThanFunc.Call([]cty.Value{a, b}) | ||
385 | } | ||
386 | |||
387 | // LessThanOrEqualTo returns true if a is less than b. | ||
388 | func LessThanOrEqualTo(a cty.Value, b cty.Value) (cty.Value, error) { | ||
389 | return LessThanOrEqualToFunc.Call([]cty.Value{a, b}) | ||
390 | } | ||
391 | |||
392 | // GreaterThan returns true if a is less than b. | ||
393 | func GreaterThan(a cty.Value, b cty.Value) (cty.Value, error) { | ||
394 | return GreaterThanFunc.Call([]cty.Value{a, b}) | ||
395 | } | ||
396 | |||
397 | // GreaterThanOrEqualTo returns true if a is less than b. | ||
398 | func GreaterThanOrEqualTo(a cty.Value, b cty.Value) (cty.Value, error) { | ||
399 | return GreaterThanOrEqualToFunc.Call([]cty.Value{a, b}) | ||
400 | } | ||
401 | |||
402 | // Modulo returns the remainder of a divided by b under integer division, | ||
403 | // where both a and b are numbers. | ||
404 | func Modulo(a cty.Value, b cty.Value) (cty.Value, error) { | ||
405 | return ModuloFunc.Call([]cty.Value{a, b}) | ||
406 | } | ||
407 | |||
408 | // Min returns the minimum number from the given numbers. | ||
409 | func Min(numbers ...cty.Value) (cty.Value, error) { | ||
410 | return MinFunc.Call(numbers) | ||
411 | } | ||
412 | |||
413 | // Max returns the maximum number from the given numbers. | ||
414 | func Max(numbers ...cty.Value) (cty.Value, error) { | ||
415 | return MaxFunc.Call(numbers) | ||
416 | } | ||
417 | |||
418 | // Int removes the fractional component of the given number returning an | ||
419 | // integer representing the whole number component, rounding towards zero. | ||
420 | // For example, -1.5 becomes -1. | ||
421 | // | ||
422 | // If an infinity is passed to Int, an error is returned. | ||
423 | func Int(num cty.Value) (cty.Value, error) { | ||
424 | if num == cty.PositiveInfinity || num == cty.NegativeInfinity { | ||
425 | return cty.NilVal, fmt.Errorf("can't truncate infinity to an integer") | ||
426 | } | ||
427 | return IntFunc.Call([]cty.Value{num}) | ||
428 | } | ||