-
Notifications
You must be signed in to change notification settings - Fork 2
/
type_codes.go
97 lines (84 loc) · 1.78 KB
/
type_codes.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
package nject
// TODO: switch from typeCode to reflect.Type -- duplicate detection would be lost
import (
"reflect"
"sync"
"github.com/muir/reflectutils"
)
type typeCode int
type typeCodes []typeCode
var (
typeCounter = 0
lock sync.Mutex
typeMap = make(map[reflect.Type]typeCode)
reverseMap = make(map[typeCode]reflect.Type)
)
type noType bool
const noTypeExampleValue noType = false
var noTypeCode = getTypeCode(noTypeExampleValue)
// noNoType filters out noTypeCode from an array of typeCode
func noNoType(types []typeCode) []typeCode {
found := -1
for i, t := range types {
if t == noTypeCode {
found = i
break
}
}
if found == -1 {
return types
}
n := make([]typeCode, found, len(types)-1)
copy(n, types[0:found])
for i := found + 1; i < len(types); i++ {
if types[i] != noTypeCode {
n = append(n, types[i])
}
}
return n
}
// getTypeCode maps reflect.Type to integers.
func getTypeCode(a interface{}) typeCode {
if a == nil {
panic("nil has no type")
}
t, isType := a.(reflect.Type)
if !isType {
t = reflect.TypeOf(a)
}
lock.Lock()
defer lock.Unlock()
if tc, found := typeMap[t]; found {
return tc
}
typeCounter++
tc := typeCode(typeCounter)
typeMap[t] = tc
reverseMap[tc] = t
return tc
}
// Type returns the reflect.Type for this typeCode
func (tc typeCode) Type() reflect.Type {
lock.Lock()
defer lock.Unlock()
return reverseMap[tc]
}
// Type returns the reflect.Type for this typeCode
func (tc typeCode) String() string {
return reflectutils.TypeName(tc.Type())
}
func (tcs typeCodes) Types() []reflect.Type {
if tcs == nil {
return nil
}
if len(tcs) == 0 {
return []reflect.Type{}
}
lock.Lock()
defer lock.Unlock()
t := make([]reflect.Type, len(tcs))
for i, tc := range tcs {
t[i] = reverseMap[tc]
}
return t
}