Этот коммит содержится в:
Damian Gryski 2023-02-25 14:24:39 -08:00 коммит произвёл Ayke
родитель d0f4702f8b
коммит f6ee470eda
2 изменённых файлов: 79 добавлений и 4 удалений

Просмотреть файл

@ -687,23 +687,53 @@ func (v Value) MapIndex(key Value) Value {
panic("unimplemented: (reflect.Value).MapIndex()")
}
//go:linkname hashmapNewIterator runtime.hashmapNewIterator
func hashmapNewIterator() unsafe.Pointer
//go:linkname hashmapNext runtime.hashmapNextUnsafePointer
func hashmapNext(m unsafe.Pointer, it unsafe.Pointer, key, value unsafe.Pointer) bool
func (v Value) MapRange() *MapIter {
panic("unimplemented: (reflect.Value).MapRange()")
if v.Kind() != Map {
panic(&ValueError{Method: "MapRange", Kind: v.Kind()})
}
return &MapIter{
m: v,
it: hashmapNewIterator(),
key: New(v.typecode.Key()),
val: New(v.typecode.Elem()),
}
}
type MapIter struct {
m Value
it unsafe.Pointer
key Value
val Value
valid bool
}
func (it *MapIter) Key() Value {
panic("unimplemented: (*reflect.MapIter).Key()")
if !it.valid {
panic("reflect.MapIter.Key called on invalid iterator")
}
return it.key.Elem()
}
func (it *MapIter) Value() Value {
panic("unimplemented: (*reflect.MapIter).Value()")
if !it.valid {
panic("reflect.MapIter.Value called on invalid iterator")
}
return it.val.Elem()
}
func (it *MapIter) Next() bool {
panic("unimplemented: (*reflect.MapIter).Next()")
it.valid = hashmapNext(it.m.pointer(), it.it, it.key.value, it.val.value)
return it.valid
}
func (v Value) Set(x Value) {

Просмотреть файл

@ -2,6 +2,7 @@ package reflect_test
import (
. "reflect"
"sort"
"testing"
)
@ -53,4 +54,48 @@ func TestMap(t *testing.T) {
if got, want := two.Interface().(int), 2; got != want {
t.Errorf("MapIndex(`foo`)=%v, want %v", got, want)
}
m["bar"] = 3
m["baz"] = 4
m["qux"] = 5
it := mref.MapRange()
var gotKeys []string
for it.Next() {
k := it.Key()
v := it.Value()
kstr := k.Interface().(string)
vint := v.Interface().(int)
gotKeys = append(gotKeys, kstr)
if m[kstr] != vint {
t.Errorf("m[%v]=%v, want %v", kstr, vint, m[kstr])
}
}
var wantKeys []string
for k := range m {
wantKeys = append(wantKeys, k)
}
sort.Strings(gotKeys)
sort.Strings(wantKeys)
if !equal(gotKeys, wantKeys) {
t.Errorf("MapRange return unexpected keys: got %v, want %v", gotKeys, wantKeys)
}
}
func equal[T comparable](a, b []T) bool {
if len(a) != len(b) {
return false
}
for i, aa := range a {
if b[i] != aa {
return false
}
}
return true
}