Skip to content

Commit

Permalink
reflect: let Value.Seq iterated integer implementation conform to the…
Browse files Browse the repository at this point in the history
… spec

See CL 557596,According to the go specification, the iterated variable type should be the same as the iterated integer type.

For golang#66056

Change-Id: I6a19cc211d081ebd8142c5a702601c8b49a6d736
  • Loading branch information
qiulaidongfeng committed May 9, 2024
1 parent 524a774 commit 4e8b711
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 16 deletions.
49 changes: 33 additions & 16 deletions src/reflect/iter.go
Expand Up @@ -6,6 +6,17 @@ package reflect

import "iter"

func rangeNum[T int8 | int16 | int32 | int64 | int | uint8 | uint16 | uint32 | uint64 | uint | uintptr, N int64 | uint64](v N) iter.Seq[Value] {
return func(yield func(v Value) bool) {
// cannot use range T(v) because no core type.
for i := T(0); i < T(v); i++ {
if !yield(ValueOf(i)) {
return
}
}
}
}

// Seq returns an iter.Seq[reflect.Value] that loops over the elements of v.
// If v's kind is Func, it must be a function that has no results and
// that takes a single argument of type func(T) bool for some type T.
Expand All @@ -22,22 +33,28 @@ func (v Value) Seq() iter.Seq[Value] {
}
}
switch v.Kind() {
case Int, Int8, Int16, Int32, Int64:
return func(yield func(Value) bool) {
for i := range v.Int() {
if !yield(ValueOf(i)) {
return
}
}
}
case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
return func(yield func(Value) bool) {
for i := range v.Uint() {
if !yield(ValueOf(i)) {
return
}
}
}
case Int:
return rangeNum[int](v.Int())
case Int8:
return rangeNum[int8](v.Int())
case Int16:
return rangeNum[int16](v.Int())
case Int32:
return rangeNum[int32](v.Int())
case Int64:
return rangeNum[int64](v.Int())
case Uint:
return rangeNum[uint](v.Uint())
case Uint8:
return rangeNum[uint8](v.Uint())
case Uint16:
return rangeNum[uint16](v.Uint())
case Uint32:
return rangeNum[uint32](v.Uint())
case Uint64:
return rangeNum[uint64](v.Uint())
case Uintptr:
return rangeNum[uintptr](v.Uint())
case Pointer:
if v.Elem().kind() != Array {
break
Expand Down
24 changes: 24 additions & 0 deletions src/reflect/iter_test.go
Expand Up @@ -40,6 +40,18 @@ func TestValueSeq(t *testing.T) {
t.Fatalf("should loop four times")
}
}},
{"int8", ValueOf(int8(4)), func(t *testing.T, s iter.Seq[Value]) {
i := int8(0)
for v := range s {
if v.Interface().(int8) != i {
t.Fatalf("got %d, want %d", v.Int(), i)
}
i++
}
if i != 4 {
t.Fatalf("should loop four times")
}
}},
{"uint", ValueOf(uint64(4)), func(t *testing.T, s iter.Seq[Value]) {
i := uint64(0)
for v := range s {
Expand All @@ -52,6 +64,18 @@ func TestValueSeq(t *testing.T) {
t.Fatalf("should loop four times")
}
}},
{"uint8", ValueOf(uint8(4)), func(t *testing.T, s iter.Seq[Value]) {
i := uint8(0)
for v := range s {
if v.Interface().(uint8) != i {
t.Fatalf("got %d, want %d", v.Int(), i)
}
i++
}
if i != 4 {
t.Fatalf("should loop four times")
}
}},
{"*[4]int", ValueOf(&[4]int{1, 2, 3, 4}), func(t *testing.T, s iter.Seq[Value]) {
i := int64(0)
for v := range s {
Expand Down

0 comments on commit 4e8b711

Please sign in to comment.