diff --git a/src/internal/reflectlite/value.go b/src/internal/reflectlite/value.go index 31015cbd27..22a6628562 100644 --- a/src/internal/reflectlite/value.go +++ b/src/internal/reflectlite/value.go @@ -1102,20 +1102,9 @@ func hashmapNewIterator() unsafe.Pointer func hashmapNext(m unsafe.Pointer, it unsafe.Pointer, key, value unsafe.Pointer) bool func (v Value) MapRange() *MapIter { - if v.Kind() != Map { - panic(&ValueError{Method: "MapRange", Kind: v.Kind()}) - } - - keyType := v.typecode.key() - - keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0 - shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !keyType.isBinary() - - return &MapIter{ - m: v, - it: hashmapNewIterator(), - unpackKeyInterface: shouldUnpackInterface, - } + iter := &MapIter{} + iter.Reset(v) + return iter } type MapIter struct { @@ -1142,6 +1131,10 @@ func (it *MapIter) Key() Value { return it.key.Elem() } +func (v Value) SetIterKey(iter *MapIter) { + v.Set(iter.Key()) +} + func (it *MapIter) Value() Value { if !it.valid { panic("reflect.MapIter.Value called on invalid iterator") @@ -1150,6 +1143,10 @@ func (it *MapIter) Value() Value { return it.val.Elem() } +func (v Value) SetIterValue(iter *MapIter) { + v.Set(iter.Value()) +} + func (it *MapIter) Next() bool { it.key = New(it.m.typecode.Key()) it.val = New(it.m.typecode.Elem()) @@ -1158,6 +1155,23 @@ func (it *MapIter) Next() bool { return it.valid } +func (iter *MapIter) Reset(v Value) { + if v.Kind() != Map { + panic(&ValueError{Method: "MapRange", Kind: v.Kind()}) + } + + keyType := v.typecode.key() + + keyTypeIsEmptyInterface := keyType.Kind() == Interface && keyType.NumMethod() == 0 + shouldUnpackInterface := !keyTypeIsEmptyInterface && keyType.Kind() != String && !keyType.isBinary() + + *iter = MapIter{ + m: v, + it: hashmapNewIterator(), + unpackKeyInterface: shouldUnpackInterface, + } +} + func (v Value) Set(x Value) { v.checkAddressable() v.checkRO() diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go index 436bc00341..b009c325a8 100644 --- a/src/reflect/all_test.go +++ b/src/reflect/all_test.go @@ -381,8 +381,6 @@ func TestSetValue(t *testing.T) { } } -/* - func TestMapIterSet(t *testing.T) { m := make(map[string]any, len(valueTests)) for _, tt := range valueTests { @@ -430,8 +428,6 @@ func TestMapIterSet(t *testing.T) { } } -*/ - func TestCanIntUintFloatComplex(t *testing.T) { type integer int type uinteger uint @@ -7955,6 +7951,8 @@ func TestConvertibleTo(t *testing.T) { } } +*/ + func TestSetIter(t *testing.T) { data := map[string]int{ "foo": 1, @@ -8044,6 +8042,8 @@ func TestSetIter(t *testing.T) { } } +/* + func TestMethodCallValueCodePtr(t *testing.T) { m := ValueOf(Point{}).Method(1) want := MethodValueCallCodePtr() diff --git a/src/reflect/value.go b/src/reflect/value.go index 026ea02060..5d8c25f2d1 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -65,14 +65,26 @@ func (it *MapIter) Key() Value { return Value{((*reflectlite.MapIter)(it)).Key()} } +func (v Value) SetIterKey(iter *MapIter) { + v.Value.SetIterKey((*reflectlite.MapIter)(iter)) +} + func (it *MapIter) Value() Value { return Value{((*reflectlite.MapIter)(it)).Value()} } +func (v Value) SetIterValue(iter *MapIter) { + v.Value.SetIterValue((*reflectlite.MapIter)(iter)) +} + func (it *MapIter) Next() bool { return ((*reflectlite.MapIter)(it)).Next() } +func (iter *MapIter) Reset(v Value) { + (*reflectlite.MapIter)(iter).Reset(v.Value) +} + func (v Value) Set(x Value) { v.Value.Set(x.Value) }