-
Notifications
You must be signed in to change notification settings - Fork 7
/
field_debug.go
50 lines (44 loc) · 1.22 KB
/
field_debug.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
//go:build debug
package xunsafe
import (
"fmt"
"reflect"
"unsafe"
)
func (f *Field) MustBeAssignable(y interface{}) {
xType := f.Type
var yType reflect.Type
var ok bool
yType, ok = y.(reflect.Type)
if !ok {
yType = reflect.TypeOf(y)
}
if xType != yType && xType.Kind() != reflect.Interface {
panic(fmt.Errorf("xunsafe.SetValue: types mismatch: wanted %v, got %v", xType.String(), yType.String()))
}
}
//Set sets only non pointer value, the reason for this limited functionality method is speed,
//its 20x faster than SetValue
//go:nocheckptr
func (f *Field) Set(structPtr unsafe.Pointer, source interface{}) {
f.MustBeAssignable(source)
ptr := f.Pointer(structPtr)
switch f.kind {
case reflect.String:
*(*string)(ptr) = source.(string)
case reflect.Int:
*(*int)(ptr) = source.(int)
case reflect.Int64:
*(*int64)(ptr) = source.(int64)
case reflect.Float64:
*(*float64)(ptr) = source.(float64)
case reflect.Float32:
*(*float32)(ptr) = source.(float32)
case reflect.Bool:
*(*bool)(ptr) = source.(bool)
case reflect.Ptr: //had to comment out this cast since this suppresses inlining
//*(*unsafe.Pointer)(ptr) = AsPointer(source)
default:
*(*unsafe.Pointer)(ptr) = *(*unsafe.Pointer)(asPointer(source))
}
}