-
Notifications
You must be signed in to change notification settings - Fork 8
/
utils.go
86 lines (77 loc) · 1.34 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package digit
import (
"math"
"strconv"
"github.com/andeya/gust"
)
const (
Host64bit = strconv.IntSize == 64
Host32bit = ^uint(0)>>32 == 0
)
func Abs[T gust.Digit](d T) T {
var zero T
if d < zero {
return -d
}
return d
}
func Max[T gust.Integer]() T {
var t T
switch any(t).(type) {
case int:
var max = math.MaxInt
return T(max)
case int8:
return T(math.MaxInt8)
case int16:
var max int16 = math.MaxInt16
return T(max)
case int32:
var max int32 = math.MaxInt32
return T(max)
case int64:
var max int64 = math.MaxInt64
return T(max)
case uint:
var max uint64 = math.MaxUint
return T(max)
case uint8:
var max uint8 = math.MaxUint8
return T(max)
case uint16:
var max uint16 = math.MaxUint16
return T(max)
case uint32:
var max uint32 = math.MaxUint32
return T(max)
case uint64:
var max uint64 = math.MaxUint64
return T(max)
default:
return t
}
}
func SaturatingAdd[T gust.Integer](a, b T) T {
if a < Max[T]()-b {
return a + b
}
return Max[T]()
}
func SaturatingSub[T gust.Digit](a, b T) T {
if a > b {
return a - b
}
return 0
}
func CheckedAdd[T gust.Integer](a, b T) gust.Option[T] {
if a <= Max[T]()-b {
return gust.Some(a + b)
}
return gust.None[T]()
}
func CheckedMul[T gust.Integer](a, b T) gust.Option[T] {
if a <= Max[T]()/b {
return gust.Some(a * b)
}
return gust.None[T]()
}