reflect: add SetMapIndex()
Этот коммит содержится в:
родитель
f6ee470eda
коммит
828c3169ab
2 изменённых файлов: 74 добавлений и 1 удалений
|
@ -972,8 +972,70 @@ func AppendSlice(s, t Value) Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:linkname hashmapStringSet runtime.hashmapStringSetUnsafePointer
|
||||||
|
func hashmapStringSet(m unsafe.Pointer, key string, value unsafe.Pointer)
|
||||||
|
|
||||||
|
//go:linkname hashmapBinarySet runtime.hashmapBinarySetUnsafePointer
|
||||||
|
func hashmapBinarySet(m unsafe.Pointer, key, value unsafe.Pointer)
|
||||||
|
|
||||||
|
//go:linkname hashmapStringDelete runtime.hashmapStringDeleteUnsafePointer
|
||||||
|
func hashmapStringDelete(m unsafe.Pointer, key string)
|
||||||
|
|
||||||
|
//go:linkname hashmapBinaryDelete runtime.hashmapBinaryDeleteUnsafePointer
|
||||||
|
func hashmapBinaryDelete(m unsafe.Pointer, key unsafe.Pointer)
|
||||||
|
|
||||||
func (v Value) SetMapIndex(key, elem Value) {
|
func (v Value) SetMapIndex(key, elem Value) {
|
||||||
panic("unimplemented: (reflect.Value).SetMapIndex()")
|
if v.Kind() != Map {
|
||||||
|
panic(&ValueError{Method: "SetMapIndex", Kind: v.Kind()})
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare key type with actual key type of map
|
||||||
|
if key.typecode != v.typecode.key() {
|
||||||
|
panic("reflect.Value.SetMapIndex: incompatible types for key")
|
||||||
|
}
|
||||||
|
|
||||||
|
// if elem is the zero Value, it means delete
|
||||||
|
del := elem == Value{}
|
||||||
|
|
||||||
|
if !del && elem.typecode != v.typecode.elem() {
|
||||||
|
panic("reflect.Value.SetMapIndex: incompatible types for value")
|
||||||
|
}
|
||||||
|
|
||||||
|
if key.Kind() == String {
|
||||||
|
if del {
|
||||||
|
hashmapStringDelete(v.pointer(), *(*string)(key.value))
|
||||||
|
} else {
|
||||||
|
var elemptr unsafe.Pointer
|
||||||
|
if elem.isIndirect() || elem.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
|
||||||
|
elemptr = elem.value
|
||||||
|
} else {
|
||||||
|
elemptr = unsafe.Pointer(&elem.value)
|
||||||
|
}
|
||||||
|
hashmapStringSet(v.pointer(), *(*string)(key.value), elemptr)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if key.typecode.isBinary() {
|
||||||
|
var keyptr unsafe.Pointer
|
||||||
|
if key.isIndirect() || key.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
|
||||||
|
keyptr = key.value
|
||||||
|
} else {
|
||||||
|
keyptr = unsafe.Pointer(&key.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if del {
|
||||||
|
hashmapBinaryDelete(v.pointer(), keyptr)
|
||||||
|
} else {
|
||||||
|
var elemptr unsafe.Pointer
|
||||||
|
if elem.isIndirect() || elem.typecode.Size() > unsafe.Sizeof(uintptr(0)) {
|
||||||
|
elemptr = elem.value
|
||||||
|
} else {
|
||||||
|
elemptr = unsafe.Pointer(&elem.value)
|
||||||
|
}
|
||||||
|
hashmapBinarySet(v.pointer(), keyptr, elemptr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic("unimplemented: (reflect.Value).MapIndex()")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldByIndex returns the nested field corresponding to index.
|
// FieldByIndex returns the nested field corresponding to index.
|
||||||
|
|
|
@ -85,6 +85,17 @@ func TestMap(t *testing.T) {
|
||||||
if !equal(gotKeys, wantKeys) {
|
if !equal(gotKeys, wantKeys) {
|
||||||
t.Errorf("MapRange return unexpected keys: got %v, want %v", gotKeys, wantKeys)
|
t.Errorf("MapRange return unexpected keys: got %v, want %v", gotKeys, wantKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mref.SetMapIndex(ValueOf("bar"), Value{})
|
||||||
|
if _, ok := m["bar"]; ok {
|
||||||
|
t.Errorf("SetMapIndex failed to delete `bar`")
|
||||||
|
}
|
||||||
|
|
||||||
|
mref.SetMapIndex(ValueOf("baz"), ValueOf(6))
|
||||||
|
if got, want := m["baz"], 6; got != want {
|
||||||
|
t.Errorf("SetMapIndex(bar, 6) got %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func equal[T comparable](a, b []T) bool {
|
func equal[T comparable](a, b []T) bool {
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче