-
Notifications
You must be signed in to change notification settings - Fork 78
/
Copy pathgeneric.go
132 lines (116 loc) · 2.78 KB
/
generic.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package generic
import (
"golang.org/x/exp/constraints"
"github.com/segmentio/fasthash/fnv1a"
)
// EqualsFn is a function that returns whether 'a' and 'b' are equal.
type EqualsFn[T any] func(a, b T) bool
// LessFn is a function that returns whether 'a' is less than 'b'.
type LessFn[T any] func(a, b T) bool
// HashFn is a function that returns the hash of 't'.
type HashFn[T any] func(t T) uint64
// Equals wraps the '==' operator for comparable types.
func Equals[T comparable](a, b T) bool {
return a == b
}
// Less wraps the '<' operator for ordered types.
func Less[T constraints.Ordered](a, b T) bool {
return a < b
}
// Compare uses a less function to determine the ordering of 'a' and 'b'. It returns:
//
// * -1 if a < b
//
// * 1 if a > b
//
// * 0 if a == b
func Compare[T any](a, b T, less LessFn[T]) int {
if less(a, b) {
return -1
} else if less(b, a) {
return 1
}
return 0
}
// Max returns the max of a and b.
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
// Min returns the min of a and b.
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
// Clamp returns x constrained within [lo:hi] range.
// If x compares less than lo, returns lo; otherwise if hi compares less than x, returns hi; otherwise returns v.
func Clamp[T constraints.Ordered](x, lo, hi T) T {
return Max(lo, Min(hi, x))
}
// MaxFunc returns the max of a and b using the less func.
func MaxFunc[T any](a, b T, less LessFn[T]) T {
if less(b, a) {
return a
}
return b
}
// MinFunc returns the min of a and b using the less func.
func MinFunc[T any](a, b T, less LessFn[T]) T {
if less(a, b) {
return a
}
return b
}
// ClampFunc returns x constrained within [lo:hi] range using the less func.
// If x compares less than lo, returns lo; otherwise if hi compares less than x, returns hi; otherwise returns v.
func ClampFunc[T any](x, lo, hi T, less LessFn[T]) T {
return MaxFunc(lo, MinFunc(hi, x, less), less)
}
func HashUint64(u uint64) uint64 {
return hash(u)
}
func HashUint32(u uint32) uint64 {
return hash(uint64(u))
}
func HashUint16(u uint16) uint64 {
return hash(uint64(u))
}
func HashUint8(u uint8) uint64 {
return hash(uint64(u))
}
func HashInt64(i int64) uint64 {
return hash(uint64(i))
}
func HashInt32(i int32) uint64 {
return hash(uint64(i))
}
func HashInt16(i int16) uint64 {
return hash(uint64(i))
}
func HashInt8(i int8) uint64 {
return hash(uint64(i))
}
func HashInt(i int) uint64 {
return hash(uint64(i))
}
func HashUint(i uint) uint64 {
return hash(uint64(i))
}
func HashString(s string) uint64 {
return fnv1a.HashString64(s)
}
func HashBytes(b []byte) uint64 {
return fnv1a.HashBytes64(b)
}
func hash(u uint64) uint64 {
u ^= u >> 33
u *= 0xff51afd7ed558ccd
u ^= u >> 33
u *= 0xc4ceb9fe1a85ec53
u ^= u >> 33
return u
}