// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package reflect

import 

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

// Seq returns an iter.Seq[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.
// If v's kind is Pointer, the pointer element type must have kind Array.
// Otherwise v's kind must be Int, Int8, Int16, Int32, Int64,
// Uint, Uint8, Uint16, Uint32, Uint64, Uintptr,
// Array, Chan, Map, Slice, or String.
func ( Value) () iter.Seq[Value] {
	if canRangeFunc(.typ()) {
		return func( func(Value) bool) {
			 := MakeFunc(.Type().In(0), func( []Value) []Value {
				return []Value{ValueOf(([0]))}
			})
			.Call([]Value{})
		}
	}
	switch .Kind() {
	case Int:
		return rangeNum[int](.Int())
	case Int8:
		return rangeNum[int8](.Int())
	case Int16:
		return rangeNum[int16](.Int())
	case Int32:
		return rangeNum[int32](.Int())
	case Int64:
		return rangeNum[int64](.Int())
	case Uint:
		return rangeNum[uint](.Uint())
	case Uint8:
		return rangeNum[uint8](.Uint())
	case Uint16:
		return rangeNum[uint16](.Uint())
	case Uint32:
		return rangeNum[uint32](.Uint())
	case Uint64:
		return rangeNum[uint64](.Uint())
	case Uintptr:
		return rangeNum[uintptr](.Uint())
	case Pointer:
		if .Elem().kind() != Array {
			break
		}
		return func( func(Value) bool) {
			 = .Elem()
			for  := range .Len() {
				if !(ValueOf()) {
					return
				}
			}
		}
	case Array, Slice:
		return func( func(Value) bool) {
			for  := range .Len() {
				if !(ValueOf()) {
					return
				}
			}
		}
	case String:
		return func( func(Value) bool) {
			for  := range .String() {
				if !(ValueOf()) {
					return
				}
			}
		}
	case Map:
		return func( func(Value) bool) {
			 := .MapRange()
			for .Next() {
				if !(.Key()) {
					return
				}
			}
		}
	case Chan:
		return func( func(Value) bool) {
			for ,  := .Recv(); ; ,  = .Recv() {
				if !() {
					return
				}
			}
		}
	}
	panic("reflect: " + .Type().String() + " cannot produce iter.Seq[Value]")
}

// Seq2 returns an iter.Seq2[Value, 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(K, V) bool for some type K, V.
// If v's kind is Pointer, the pointer element type must have kind Array.
// Otherwise v's kind must be Array, Map, Slice, or String.
func ( Value) () iter.Seq2[Value, Value] {
	if canRangeFunc2(.typ()) {
		return func( func(Value, Value) bool) {
			 := MakeFunc(.Type().In(0), func( []Value) []Value {
				return []Value{ValueOf(([0], [1]))}
			})
			.Call([]Value{})
		}
	}
	switch .Kind() {
	case Pointer:
		if .Elem().kind() != Array {
			break
		}
		return func( func(Value, Value) bool) {
			 = .Elem()
			for  := range .Len() {
				if !(ValueOf(), .Index()) {
					return
				}
			}
		}
	case Array, Slice:
		return func( func(Value, Value) bool) {
			for  := range .Len() {
				if !(ValueOf(), .Index()) {
					return
				}
			}
		}
	case String:
		return func( func(Value, Value) bool) {
			for ,  := range .String() {
				if !(ValueOf(), ValueOf()) {
					return
				}
			}
		}
	case Map:
		return func( func(Value, Value) bool) {
			 := .MapRange()
			for .Next() {
				if !(.Key(), .Value()) {
					return
				}
			}
		}
	}
	panic("reflect: " + .Type().String() + " cannot produce iter.Seq2[Value, Value]")
}