Source file src/reflect/iter.go

     1  // Copyright 2024 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package reflect
     6  
     7  import (
     8  	"iter"
     9  )
    10  
    11  func rangeNum[T int8 | int16 | int32 | int64 | int |
    12  	uint8 | uint16 | uint32 | uint64 | uint |
    13  	uintptr, N int64 | uint64](num N, t Type) iter.Seq[Value] {
    14  	return func(yield func(v Value) bool) {
    15  		convert := t.PkgPath() != ""
    16  		// cannot use range T(v) because no core type.
    17  		for i := T(0); i < T(num); i++ {
    18  			tmp := ValueOf(i)
    19  			// if the iteration value type is define by
    20  			// type T built-in type.
    21  			if convert {
    22  				tmp = tmp.Convert(t)
    23  			}
    24  			if !yield(tmp) {
    25  				return
    26  			}
    27  		}
    28  	}
    29  }
    30  
    31  // Seq returns an iter.Seq[Value] that loops over the elements of v.
    32  // If v's kind is Func, it must be a function that has no results and
    33  // that takes a single argument of type func(T) bool for some type T.
    34  // If v's kind is Pointer, the pointer element type must have kind Array.
    35  // Otherwise v's kind must be Int, Int8, Int16, Int32, Int64,
    36  // Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
    37  // Array, Chan, Map, Slice, or String.
    38  func (v Value) Seq() iter.Seq[Value] {
    39  	if canRangeFunc(v.abiType()) {
    40  		return func(yield func(Value) bool) {
    41  			rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
    42  				return []Value{ValueOf(yield(in[0]))}
    43  			})
    44  			v.Call([]Value{rf})
    45  		}
    46  	}
    47  	switch v.kind() {
    48  	case Int:
    49  		return rangeNum[int](v.Int(), v.Type())
    50  	case Int8:
    51  		return rangeNum[int8](v.Int(), v.Type())
    52  	case Int16:
    53  		return rangeNum[int16](v.Int(), v.Type())
    54  	case Int32:
    55  		return rangeNum[int32](v.Int(), v.Type())
    56  	case Int64:
    57  		return rangeNum[int64](v.Int(), v.Type())
    58  	case Uint:
    59  		return rangeNum[uint](v.Uint(), v.Type())
    60  	case Uint8:
    61  		return rangeNum[uint8](v.Uint(), v.Type())
    62  	case Uint16:
    63  		return rangeNum[uint16](v.Uint(), v.Type())
    64  	case Uint32:
    65  		return rangeNum[uint32](v.Uint(), v.Type())
    66  	case Uint64:
    67  		return rangeNum[uint64](v.Uint(), v.Type())
    68  	case Uintptr:
    69  		return rangeNum[uintptr](v.Uint(), v.Type())
    70  	case Pointer:
    71  		if v.Elem().kind() != Array {
    72  			break
    73  		}
    74  		return func(yield func(Value) bool) {
    75  			v = v.Elem()
    76  			for i := range v.Len() {
    77  				if !yield(ValueOf(i)) {
    78  					return
    79  				}
    80  			}
    81  		}
    82  	case Array, Slice:
    83  		return func(yield func(Value) bool) {
    84  			for i := range v.Len() {
    85  				if !yield(ValueOf(i)) {
    86  					return
    87  				}
    88  			}
    89  		}
    90  	case String:
    91  		return func(yield func(Value) bool) {
    92  			for i := range v.String() {
    93  				if !yield(ValueOf(i)) {
    94  					return
    95  				}
    96  			}
    97  		}
    98  	case Map:
    99  		return func(yield func(Value) bool) {
   100  			i := v.MapRange()
   101  			for i.Next() {
   102  				if !yield(i.Key()) {
   103  					return
   104  				}
   105  			}
   106  		}
   107  	case Chan:
   108  		return func(yield func(Value) bool) {
   109  			for value, ok := v.Recv(); ok; value, ok = v.Recv() {
   110  				if !yield(value) {
   111  					return
   112  				}
   113  			}
   114  		}
   115  	}
   116  	panic("reflect: " + v.Type().String() + " cannot produce iter.Seq[Value]")
   117  }
   118  
   119  // Seq2 returns an iter.Seq2[Value, Value] that loops over the elements of v.
   120  // If v's kind is Func, it must be a function that has no results and
   121  // that takes a single argument of type func(K, V) bool for some type K, V.
   122  // If v's kind is Pointer, the pointer element type must have kind Array.
   123  // Otherwise v's kind must be Array, Map, Slice, or String.
   124  func (v Value) Seq2() iter.Seq2[Value, Value] {
   125  	if canRangeFunc2(v.abiType()) {
   126  		return func(yield func(Value, Value) bool) {
   127  			rf := MakeFunc(v.Type().In(0), func(in []Value) []Value {
   128  				return []Value{ValueOf(yield(in[0], in[1]))}
   129  			})
   130  			v.Call([]Value{rf})
   131  		}
   132  	}
   133  	switch v.Kind() {
   134  	case Pointer:
   135  		if v.Elem().kind() != Array {
   136  			break
   137  		}
   138  		return func(yield func(Value, Value) bool) {
   139  			v = v.Elem()
   140  			for i := range v.Len() {
   141  				if !yield(ValueOf(i), v.Index(i)) {
   142  					return
   143  				}
   144  			}
   145  		}
   146  	case Array, Slice:
   147  		return func(yield func(Value, Value) bool) {
   148  			for i := range v.Len() {
   149  				if !yield(ValueOf(i), v.Index(i)) {
   150  					return
   151  				}
   152  			}
   153  		}
   154  	case String:
   155  		return func(yield func(Value, Value) bool) {
   156  			for i, v := range v.String() {
   157  				if !yield(ValueOf(i), ValueOf(v)) {
   158  					return
   159  				}
   160  			}
   161  		}
   162  	case Map:
   163  		return func(yield func(Value, Value) bool) {
   164  			i := v.MapRange()
   165  			for i.Next() {
   166  				if !yield(i.Key(), i.Value()) {
   167  					return
   168  				}
   169  			}
   170  		}
   171  	}
   172  	panic("reflect: " + v.Type().String() + " cannot produce iter.Seq2[Value, Value]")
   173  }
   174  

View as plain text