summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/modern-go/reflect2/unsafe_map.go
blob: f2e76e6bb1491d1d47253252d66433386446ffc1 (plain) (blame)
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
133
134
135
136
137
138
package reflect2

import (
	"reflect"
	"unsafe"
)

type UnsafeMapType struct {
	unsafeType
	pKeyRType  unsafe.Pointer
	pElemRType unsafe.Pointer
}

func newUnsafeMapType(cfg *frozenConfig, type1 reflect.Type) MapType {
	return &UnsafeMapType{
		unsafeType: *newUnsafeType(cfg, type1),
		pKeyRType:  unpackEFace(reflect.PtrTo(type1.Key())).data,
		pElemRType: unpackEFace(reflect.PtrTo(type1.Elem())).data,
	}
}

func (type2 *UnsafeMapType) IsNil(obj interface{}) bool {
	if obj == nil {
		return true
	}
	objEFace := unpackEFace(obj)
	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
	return type2.UnsafeIsNil(objEFace.data)
}

func (type2 *UnsafeMapType) UnsafeIsNil(ptr unsafe.Pointer) bool {
	if ptr == nil {
		return true
	}
	return *(*unsafe.Pointer)(ptr) == nil
}

func (type2 *UnsafeMapType) LikePtr() bool {
	return true
}

func (type2 *UnsafeMapType) Indirect(obj interface{}) interface{} {
	objEFace := unpackEFace(obj)
	assertType("MapType.Indirect argument 1", type2.ptrRType, objEFace.rtype)
	return type2.UnsafeIndirect(objEFace.data)
}

func (type2 *UnsafeMapType) UnsafeIndirect(ptr unsafe.Pointer) interface{} {
	return packEFace(type2.rtype, *(*unsafe.Pointer)(ptr))
}

func (type2 *UnsafeMapType) Key() Type {
	return type2.cfg.Type2(type2.Type.Key())
}

func (type2 *UnsafeMapType) MakeMap(cap int) interface{} {
	return packEFace(type2.ptrRType, type2.UnsafeMakeMap(cap))
}

func (type2 *UnsafeMapType) UnsafeMakeMap(cap int) unsafe.Pointer {
	m := makeMapWithSize(type2.rtype, cap)
	return unsafe.Pointer(&m)
}

func (type2 *UnsafeMapType) SetIndex(obj interface{}, key interface{}, elem interface{}) {
	objEFace := unpackEFace(obj)
	assertType("MapType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
	keyEFace := unpackEFace(key)
	assertType("MapType.SetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
	elemEFace := unpackEFace(elem)
	assertType("MapType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
	type2.UnsafeSetIndex(objEFace.data, keyEFace.data, elemEFace.data)
}

func (type2 *UnsafeMapType) UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer) {
	mapassign(type2.rtype, *(*unsafe.Pointer)(obj), key, elem)
}

func (type2 *UnsafeMapType) TryGetIndex(obj interface{}, key interface{}) (interface{}, bool) {
	objEFace := unpackEFace(obj)
	assertType("MapType.TryGetIndex argument 1", type2.ptrRType, objEFace.rtype)
	keyEFace := unpackEFace(key)
	assertType("MapType.TryGetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
	elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data)
	if elemPtr == nil {
		return nil, false
	}
	return packEFace(type2.pElemRType, elemPtr), true
}

func (type2 *UnsafeMapType) GetIndex(obj interface{}, key interface{}) interface{} {
	objEFace := unpackEFace(obj)
	assertType("MapType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
	keyEFace := unpackEFace(key)
	assertType("MapType.GetIndex argument 2", type2.pKeyRType, keyEFace.rtype)
	elemPtr := type2.UnsafeGetIndex(objEFace.data, keyEFace.data)
	return packEFace(type2.pElemRType, elemPtr)
}

func (type2 *UnsafeMapType) UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer {
	return mapaccess(type2.rtype, *(*unsafe.Pointer)(obj), key)
}

func (type2 *UnsafeMapType) Iterate(obj interface{}) MapIterator {
	objEFace := unpackEFace(obj)
	assertType("MapType.Iterate argument 1", type2.ptrRType, objEFace.rtype)
	return type2.UnsafeIterate(objEFace.data)
}

func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
	return &UnsafeMapIterator{
		hiter:      mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)),
		pKeyRType:  type2.pKeyRType,
		pElemRType: type2.pElemRType,
	}
}

type UnsafeMapIterator struct {
	*hiter
	pKeyRType  unsafe.Pointer
	pElemRType unsafe.Pointer
}

func (iter *UnsafeMapIterator) HasNext() bool {
	return iter.key != nil
}

func (iter *UnsafeMapIterator) Next() (interface{}, interface{}) {
	key, elem := iter.UnsafeNext()
	return packEFace(iter.pKeyRType, key), packEFace(iter.pElemRType, elem)
}

func (iter *UnsafeMapIterator) UnsafeNext() (unsafe.Pointer, unsafe.Pointer) {
	key := iter.key
	elem := iter.value
	mapiternext(iter.hiter)
	return key, elem
}