diff --git a/gen_norangefunc.go b/gen_norangefunc.go new file mode 100644 index 0000000..3587e57 --- /dev/null +++ b/gen_norangefunc.go @@ -0,0 +1,307 @@ +// Code generated by internal/gen. DO NOT EDIT. + +//go:build !goexperiment.rangefunc + +package xiter + +import ( + "cmp" + "context" + "reflect" + "unsafe" +) + +func All[T any](seq Seq[T], f func(T) bool) bool { + _r0 := _All(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0 +} + +func Any[T any](seq Seq[T], f func(T) bool) bool { + _r0 := _Any(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0 +} + +func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { + _r0, _r1 := _AppendSplitTo(seq, s1, s2) + return _r0, _r1 +} + +func AppendTo[T any, S ~[]T](seq Seq[T], s S) S { + _r0 := _AppendTo(*(*_Seq[T])(unsafe.Pointer(&seq)), s) + return _r0 +} + +func Bytes(s string) Seq[byte] { + _r0 := _Bytes(s) + return Seq[byte](_r0) +} + +func Cache[T any](seq Seq[T]) Seq[T] { + _r0 := _Cache(*(*_Seq[T])(unsafe.Pointer(&seq))) + return Seq[T](_r0) +} + +func Chunks[T any](seq Seq[T], n int) Seq[[]T] { + _r0 := _Chunks(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return Seq[[]T](_r0) +} + +func Collect[T any](seq Seq[T]) []T { + _r0 := _Collect(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func CollectSize[T any](seq Seq[T], len int) []T { + _r0 := _CollectSize(*(*_Seq[T])(unsafe.Pointer(&seq)), len) + return _r0 +} + +func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { + _r0, _r1 := _CollectSplit(seq) + return _r0, _r1 +} + +func Concat[T any](seqs ...Seq[T]) Seq[T] { + _r0 := _Concat(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) + return Seq[T](_r0) +} + +func Contains[T comparable](seq Seq[T], v T) bool { + _r0 := _Contains(*(*_Seq[T])(unsafe.Pointer(&seq)), v) + return _r0 +} + +func Drain[T any](seq Seq[T]) { + _Drain(*(*_Seq[T])(unsafe.Pointer(&seq))) + +} + +func Enumerate[T any](seq Seq[T]) Seq2[int, T] { + _r0 := _Enumerate(*(*_Seq[T])(unsafe.Pointer(&seq))) + return Seq2[int, T](_r0) +} + +func Equal[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) bool { + _r0 := _Equal(*(*_Seq[T])(unsafe.Pointer(&seq1)), *(*_Seq[T])(unsafe.Pointer(&seq2))) + return _r0 +} + +func EqualFunc[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2], equal func(T1, T2) bool) bool { + _r0 := _EqualFunc(*(*_Seq[T1])(unsafe.Pointer(&seq1)), *(*_Seq[T2])(unsafe.Pointer(&seq2)), equal) + return _r0 +} + +func Filter[T any](seq Seq[T], f func(T) bool) Seq[T] { + _r0 := _Filter(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return Seq[T](_r0) +} + +func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool) { + _r0, _r1 := _Find(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0, _r1 +} + +func Flatten[T any](seq Seq[Seq[T]]) Seq[T] { + _r0 := _Flatten(*(*_Seq[_Seq[T]])(unsafe.Pointer(&seq))) + return Seq[T](_r0) +} + +func Fold[T any](seq Seq[T], reducer func(T, T) T) T { + _r0 := _Fold(*(*_Seq[T])(unsafe.Pointer(&seq)), reducer) + return _r0 +} + +func FromPair[T1 any, T2 any](seq Seq[Pair[T1, T2]]) Seq2[T1, T2] { + _r0 := _FromPair(*(*_Seq[Pair[T1, T2]])(unsafe.Pointer(&seq))) + return Seq2[T1, T2](_r0) +} + +func Generate[T Addable](start T, step T) Seq[T] { + _r0 := _Generate(start, step) + return Seq[T](_r0) +} + +func GoPull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { + _r0, _r1 := _GoPull(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0, _r1 +} + +func Handle[T any](seq Seq2[T, error], f func(error) bool) Seq[T] { + _r0 := _Handle(*(*_Seq2[T, error])(unsafe.Pointer(&seq)), f) + return Seq[T](_r0) +} + +func IsSorted[T cmp.Ordered](seq Seq[T]) bool { + _r0 := _IsSorted(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func IsSortedFunc[T any](seq Seq[T], compare func(T, T) int) bool { + _r0 := _IsSortedFunc(*(*_Seq[T])(unsafe.Pointer(&seq)), compare) + return _r0 +} + +func Limit[T any](seq Seq[T], n int) Seq[T] { + _r0 := _Limit(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return Seq[T](_r0) +} + +func Map[T1 any, T2 any](seq Seq[T1], f func(T1) T2) Seq[T2] { + _r0 := _Map(*(*_Seq[T1])(unsafe.Pointer(&seq)), f) + return Seq[T2](_r0) +} + +func MapKeys[K comparable, V any, M ~map[K]V](m M) Seq[K] { + _r0 := _MapKeys(m) + return Seq[K](_r0) +} + +func MapValues[K comparable, V any, M ~map[K]V](m M) Seq[V] { + _r0 := _MapValues(m) + return Seq[V](_r0) +} + +func Max[T cmp.Ordered](seq Seq[T]) T { + _r0 := _Max(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func Merge[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) Seq[T] { + _r0 := _Merge(*(*_Seq[T])(unsafe.Pointer(&seq1)), *(*_Seq[T])(unsafe.Pointer(&seq2))) + return Seq[T](_r0) +} + +func MergeFunc[T any](seq1 Seq[T], seq2 Seq[T], compare func(T, T) int) Seq[T] { + _r0 := _MergeFunc(*(*_Seq[T])(unsafe.Pointer(&seq1)), *(*_Seq[T])(unsafe.Pointer(&seq2)), compare) + return Seq[T](_r0) +} + +func Min[T cmp.Ordered](seq Seq[T]) T { + _r0 := _Min(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func Of[T any](vals ...T) Seq[T] { + _r0 := _Of(vals...) + return Seq[T](_r0) +} + +func OfChan[T any](c <-chan T) Seq[T] { + _r0 := _OfChan(c) + return Seq[T](_r0) +} + +func OfMap[K comparable, V any, M ~map[K]V](m M) Seq2[K, V] { + _r0 := _OfMap(m) + return Seq2[K, V](_r0) +} + +func OfSlice[T any, S ~[]T](s S) Seq[T] { + _r0 := _OfSlice(s) + return Seq[T](_r0) +} + +func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] { + _r0 := _OfSliceIndex(s) + return Seq2[int, T](_r0) +} + +func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { + _r0 := _OfValue(v) + return Seq2[reflect.Value, reflect.Value](_r0) +} + +func Or[T any](seqs ...Seq[T]) Seq[T] { + _r0 := _Or(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) + return Seq[T](_r0) +} + +func Partition[T any](seq Seq[T], f func(T) bool) (true []T, false []T) { + _r0, _r1 := _Partition(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0, _r1 +} + +func PartitionInto[T any](seq Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { + _r0, _r1 := _PartitionInto(*(*_Seq[T])(unsafe.Pointer(&seq)), f, true, false) + return _r0, _r1 +} + +func Product[T Multiplyable](seq Seq[T]) T { + _r0 := _Product(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func Pull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { + _r0, _r1 := _Pull(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0, _r1 +} + +func RecvContext[T any](ctx context.Context, c <-chan T) Seq[T] { + _r0 := _RecvContext(ctx, c) + return Seq[T](_r0) +} + +func Reduce[T any, R any](seq Seq[T], initial R, reducer func(R, T) R) R { + _r0 := _Reduce(*(*_Seq[T])(unsafe.Pointer(&seq)), initial, reducer) + return _r0 +} + +func Runes[T ~[]byte | ~string](s T) Seq[rune] { + _r0 := _Runes(s) + return Seq[rune](_r0) +} + +func SendContext[T any](seq Seq[T], ctx context.Context, c chan<- T) { + _SendContext(*(*_Seq[T])(unsafe.Pointer(&seq)), ctx, c) + +} + +func Skip[T any](seq Seq[T], n int) Seq[T] { + _r0 := _Skip(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return Seq[T](_r0) +} + +func Split[T any](seq Seq[T], f func(T) bool) SplitSeq[T, T] { + _r0 := _Split(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0 +} + +func Split2[T1 any, T2 any](seq Seq2[T1, T2]) SplitSeq[T1, T2] { + _r0 := _Split2(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return _r0 +} + +func StringSplit(s string, sep string) Seq[string] { + _r0 := _StringSplit(s, sep) + return Seq[string](_r0) +} + +func Sum[T Addable](seq Seq[T]) T { + _r0 := _Sum(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func ToPair[T1 any, T2 any](seq Seq2[T1, T2]) Seq[Pair[T1, T2]] { + _r0 := _ToPair(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return Seq[Pair[T1, T2]](_r0) +} + +func V1[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T1] { + _r0 := _V1(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return Seq[T1](_r0) +} + +func V2[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T2] { + _r0 := _V2(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return Seq[T2](_r0) +} + +func Windows[T any](seq Seq[T], n int) Seq[[]T] { + _r0 := _Windows(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return Seq[[]T](_r0) +} + +func Zip[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]] { + _r0 := _Zip(*(*_Seq[T1])(unsafe.Pointer(&seq1)), *(*_Seq[T2])(unsafe.Pointer(&seq2))) + return Seq[Zipped[T1, T2]](_r0) +} diff --git a/gen_rangefunc.go b/gen_rangefunc.go new file mode 100644 index 0000000..1cf05e6 --- /dev/null +++ b/gen_rangefunc.go @@ -0,0 +1,308 @@ +// Code generated by internal/gen. DO NOT EDIT. + +//go:build goexperiment.rangefunc + +package xiter + +import ( + "cmp" + "context" + "iter" + "reflect" + "unsafe" +) + +func All[T any](seq iter.Seq[T], f func(T) bool) bool { + _r0 := _All(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0 +} + +func Any[T any](seq iter.Seq[T], f func(T) bool) bool { + _r0 := _Any(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0 +} + +func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { + _r0, _r1 := _AppendSplitTo(seq, s1, s2) + return _r0, _r1 +} + +func AppendTo[T any, S ~[]T](seq iter.Seq[T], s S) S { + _r0 := _AppendTo(*(*_Seq[T])(unsafe.Pointer(&seq)), s) + return _r0 +} + +func Bytes(s string) iter.Seq[byte] { + _r0 := _Bytes(s) + return iter.Seq[byte](_r0) +} + +func Cache[T any](seq iter.Seq[T]) iter.Seq[T] { + _r0 := _Cache(*(*_Seq[T])(unsafe.Pointer(&seq))) + return iter.Seq[T](_r0) +} + +func Chunks[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { + _r0 := _Chunks(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return iter.Seq[[]T](_r0) +} + +func Collect[T any](seq iter.Seq[T]) []T { + _r0 := _Collect(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func CollectSize[T any](seq iter.Seq[T], len int) []T { + _r0 := _CollectSize(*(*_Seq[T])(unsafe.Pointer(&seq)), len) + return _r0 +} + +func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { + _r0, _r1 := _CollectSplit(seq) + return _r0, _r1 +} + +func Concat[T any](seqs ...iter.Seq[T]) iter.Seq[T] { + _r0 := _Concat(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) + return iter.Seq[T](_r0) +} + +func Contains[T comparable](seq iter.Seq[T], v T) bool { + _r0 := _Contains(*(*_Seq[T])(unsafe.Pointer(&seq)), v) + return _r0 +} + +func Drain[T any](seq iter.Seq[T]) { + _Drain(*(*_Seq[T])(unsafe.Pointer(&seq))) + +} + +func Enumerate[T any](seq iter.Seq[T]) iter.Seq2[int, T] { + _r0 := _Enumerate(*(*_Seq[T])(unsafe.Pointer(&seq))) + return iter.Seq2[int, T](_r0) +} + +func Equal[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) bool { + _r0 := _Equal(*(*_Seq[T])(unsafe.Pointer(&seq1)), *(*_Seq[T])(unsafe.Pointer(&seq2))) + return _r0 +} + +func EqualFunc[T1 any, T2 any](seq1 iter.Seq[T1], seq2 iter.Seq[T2], equal func(T1, T2) bool) bool { + _r0 := _EqualFunc(*(*_Seq[T1])(unsafe.Pointer(&seq1)), *(*_Seq[T2])(unsafe.Pointer(&seq2)), equal) + return _r0 +} + +func Filter[T any](seq iter.Seq[T], f func(T) bool) iter.Seq[T] { + _r0 := _Filter(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return iter.Seq[T](_r0) +} + +func Find[T any](seq iter.Seq[T], f func(T) bool) (r T, ok bool) { + _r0, _r1 := _Find(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0, _r1 +} + +func Flatten[T any](seq iter.Seq[iter.Seq[T]]) iter.Seq[T] { + _r0 := _Flatten(*(*_Seq[_Seq[T]])(unsafe.Pointer(&seq))) + return iter.Seq[T](_r0) +} + +func Fold[T any](seq iter.Seq[T], reducer func(T, T) T) T { + _r0 := _Fold(*(*_Seq[T])(unsafe.Pointer(&seq)), reducer) + return _r0 +} + +func FromPair[T1 any, T2 any](seq iter.Seq[Pair[T1, T2]]) iter.Seq2[T1, T2] { + _r0 := _FromPair(*(*_Seq[Pair[T1, T2]])(unsafe.Pointer(&seq))) + return iter.Seq2[T1, T2](_r0) +} + +func Generate[T Addable](start T, step T) iter.Seq[T] { + _r0 := _Generate(start, step) + return iter.Seq[T](_r0) +} + +func GoPull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { + _r0, _r1 := _GoPull(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0, _r1 +} + +func Handle[T any](seq iter.Seq2[T, error], f func(error) bool) iter.Seq[T] { + _r0 := _Handle(*(*_Seq2[T, error])(unsafe.Pointer(&seq)), f) + return iter.Seq[T](_r0) +} + +func IsSorted[T cmp.Ordered](seq iter.Seq[T]) bool { + _r0 := _IsSorted(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func IsSortedFunc[T any](seq iter.Seq[T], compare func(T, T) int) bool { + _r0 := _IsSortedFunc(*(*_Seq[T])(unsafe.Pointer(&seq)), compare) + return _r0 +} + +func Limit[T any](seq iter.Seq[T], n int) iter.Seq[T] { + _r0 := _Limit(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return iter.Seq[T](_r0) +} + +func Map[T1 any, T2 any](seq iter.Seq[T1], f func(T1) T2) iter.Seq[T2] { + _r0 := _Map(*(*_Seq[T1])(unsafe.Pointer(&seq)), f) + return iter.Seq[T2](_r0) +} + +func MapKeys[K comparable, V any, M ~map[K]V](m M) iter.Seq[K] { + _r0 := _MapKeys(m) + return iter.Seq[K](_r0) +} + +func MapValues[K comparable, V any, M ~map[K]V](m M) iter.Seq[V] { + _r0 := _MapValues(m) + return iter.Seq[V](_r0) +} + +func Max[T cmp.Ordered](seq iter.Seq[T]) T { + _r0 := _Max(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func Merge[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) iter.Seq[T] { + _r0 := _Merge(*(*_Seq[T])(unsafe.Pointer(&seq1)), *(*_Seq[T])(unsafe.Pointer(&seq2))) + return iter.Seq[T](_r0) +} + +func MergeFunc[T any](seq1 iter.Seq[T], seq2 iter.Seq[T], compare func(T, T) int) iter.Seq[T] { + _r0 := _MergeFunc(*(*_Seq[T])(unsafe.Pointer(&seq1)), *(*_Seq[T])(unsafe.Pointer(&seq2)), compare) + return iter.Seq[T](_r0) +} + +func Min[T cmp.Ordered](seq iter.Seq[T]) T { + _r0 := _Min(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func Of[T any](vals ...T) iter.Seq[T] { + _r0 := _Of(vals...) + return iter.Seq[T](_r0) +} + +func OfChan[T any](c <-chan T) iter.Seq[T] { + _r0 := _OfChan(c) + return iter.Seq[T](_r0) +} + +func OfMap[K comparable, V any, M ~map[K]V](m M) iter.Seq2[K, V] { + _r0 := _OfMap(m) + return iter.Seq2[K, V](_r0) +} + +func OfSlice[T any, S ~[]T](s S) iter.Seq[T] { + _r0 := _OfSlice(s) + return iter.Seq[T](_r0) +} + +func OfSliceIndex[T any, S ~[]T](s S) iter.Seq2[int, T] { + _r0 := _OfSliceIndex(s) + return iter.Seq2[int, T](_r0) +} + +func OfValue(v reflect.Value) iter.Seq2[reflect.Value, reflect.Value] { + _r0 := _OfValue(v) + return iter.Seq2[reflect.Value, reflect.Value](_r0) +} + +func Or[T any](seqs ...iter.Seq[T]) iter.Seq[T] { + _r0 := _Or(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) + return iter.Seq[T](_r0) +} + +func Partition[T any](seq iter.Seq[T], f func(T) bool) (true []T, false []T) { + _r0, _r1 := _Partition(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0, _r1 +} + +func PartitionInto[T any](seq iter.Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { + _r0, _r1 := _PartitionInto(*(*_Seq[T])(unsafe.Pointer(&seq)), f, true, false) + return _r0, _r1 +} + +func Product[T Multiplyable](seq iter.Seq[T]) T { + _r0 := _Product(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func Pull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { + _r0, _r1 := _Pull(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0, _r1 +} + +func RecvContext[T any](ctx context.Context, c <-chan T) iter.Seq[T] { + _r0 := _RecvContext(ctx, c) + return iter.Seq[T](_r0) +} + +func Reduce[T any, R any](seq iter.Seq[T], initial R, reducer func(R, T) R) R { + _r0 := _Reduce(*(*_Seq[T])(unsafe.Pointer(&seq)), initial, reducer) + return _r0 +} + +func Runes[T ~[]byte | ~string](s T) iter.Seq[rune] { + _r0 := _Runes(s) + return iter.Seq[rune](_r0) +} + +func SendContext[T any](seq iter.Seq[T], ctx context.Context, c chan<- T) { + _SendContext(*(*_Seq[T])(unsafe.Pointer(&seq)), ctx, c) + +} + +func Skip[T any](seq iter.Seq[T], n int) iter.Seq[T] { + _r0 := _Skip(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return iter.Seq[T](_r0) +} + +func Split[T any](seq iter.Seq[T], f func(T) bool) SplitSeq[T, T] { + _r0 := _Split(*(*_Seq[T])(unsafe.Pointer(&seq)), f) + return _r0 +} + +func Split2[T1 any, T2 any](seq iter.Seq2[T1, T2]) SplitSeq[T1, T2] { + _r0 := _Split2(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return _r0 +} + +func StringSplit(s string, sep string) iter.Seq[string] { + _r0 := _StringSplit(s, sep) + return iter.Seq[string](_r0) +} + +func Sum[T Addable](seq iter.Seq[T]) T { + _r0 := _Sum(*(*_Seq[T])(unsafe.Pointer(&seq))) + return _r0 +} + +func ToPair[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[Pair[T1, T2]] { + _r0 := _ToPair(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return iter.Seq[Pair[T1, T2]](_r0) +} + +func V1[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T1] { + _r0 := _V1(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return iter.Seq[T1](_r0) +} + +func V2[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T2] { + _r0 := _V2(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) + return iter.Seq[T2](_r0) +} + +func Windows[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { + _r0 := _Windows(*(*_Seq[T])(unsafe.Pointer(&seq)), n) + return iter.Seq[[]T](_r0) +} + +func Zip[T1 any, T2 any](seq1 iter.Seq[T1], seq2 iter.Seq[T2]) iter.Seq[Zipped[T1, T2]] { + _r0 := _Zip(*(*_Seq[T1])(unsafe.Pointer(&seq1)), *(*_Seq[T2])(unsafe.Pointer(&seq2))) + return iter.Seq[Zipped[T1, T2]](_r0) +} diff --git a/go.mod b/go.mod index a46504a..769fbac 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,7 @@ module deedles.dev/xiter -go 1.22 +go 1.21 + +require golang.org/x/tools v0.17.0 + +require golang.org/x/mod v0.14.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..84d5fdb --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= diff --git a/internal/gen/gen.go b/internal/gen/gen.go new file mode 100644 index 0000000..75789ec --- /dev/null +++ b/internal/gen/gen.go @@ -0,0 +1,246 @@ +package main + +import ( + "bytes" + "cmp" + _ "embed" + "flag" + "fmt" + "go/format" + "go/types" + "log/slog" + "os" + "regexp" + "slices" + "strings" + "text/template" + + "golang.org/x/tools/go/packages" +) + +var ( + namePattern = regexp.MustCompile(`^_[A-Z]`) + + //go:embed output.go.tmpl + outputTemplate string + tmpl = template.Must(template.New("output").Funcs(funcMap).Parse(outputTemplate)) + funcMap = map[string]any{ + "typeParamSlice": listToSlice[*types.TypeParam], + "tupleSlice": listToSlice[*types.Var], + "convertFuncName": convertFuncName, + "convertType": convertType, + "convertArg": convertArg, + "convertReturn": convertReturn, + } +) + +func convertFuncName(name string) string { + return strings.TrimPrefix(name, "_") +} + +type List[T any] interface { + At(int) T + Len() int +} + +func listToSlice[T any](list List[T]) []T { + length := list.Len() + s := make([]T, 0, length) + for i := 0; i < length; i++ { + s = append(s, list.At(i)) + } + return s +} + +func convertType(rangefunc bool, variadic bool, t types.Type) string { + switch t := t.(type) { + case *types.Named: + var pkg string + if t.Obj().Pkg() != nil && t.Obj().Pkg().Path() != "deedles.dev/xiter" { + pkg = t.Obj().Pkg().Name() + "." + } + + name := convertTypeName(rangefunc, t.Obj().Name()) + + if t.TypeArgs().Len() == 0 { + return pkg + name + } + + typeArgs := make([]string, 0, t.TypeArgs().Len()) + for _, arg := range listToSlice(t.TypeArgs()) { + typeArgs = append(typeArgs, convertType(rangefunc, false, arg)) + } + return fmt.Sprintf("%v%v[%v]", pkg, name, strings.Join(typeArgs, ",")) + + case *types.Slice: + ct := convertType(rangefunc, false, t.Elem()) + if variadic { + // TODO: Only do this if it's the last argument. Probably should + // be done in the template. + return fmt.Sprintf("...%v", ct) + } + return fmt.Sprintf("[]%v", ct) + + case *types.Interface, *types.Basic, *types.TypeParam, *types.Signature, *types.Chan: + return t.String() + + default: + return fmt.Sprintf("\"%T\"", t) + } +} + +func convertTypeName(rangefunc bool, name string) string { + cut, ok := strings.CutPrefix(name, "_") + if !ok { + return name + } + + if !rangefunc { + return cut + } + + return "iter." + cut +} + +func convertArgType(rangefunc bool, t types.Type) (from string, to string, unsafe bool, ok bool) { + switch t := t.(type) { + case *types.Named: + to := t.Obj().Name() + + if t.Obj().Pkg() == nil || t.Obj().Pkg().Path() != "deedles.dev/xiter" { + return t.String(), t.String(), false, false + } + + if t.TypeArgs().Len() != 0 { + typeArgs := make([]string, 0, t.TypeArgs().Len()) + for _, arg := range listToSlice(t.TypeArgs()) { + _, to, _, _ := convertArgType(rangefunc, arg) + typeArgs = append(typeArgs, to) + } + to = fmt.Sprintf("%v[%v]", to, strings.Join(typeArgs, ",")) + } + + from, ok := strings.CutPrefix(to, "_") + return from, to, t.TypeArgs().Len() != 0, ok + + default: + return t.String(), t.String(), false, false + } +} + +func convertArg(rangefunc bool, t types.Type, name string) string { + switch t := t.(type) { + case *types.Named: + _, to, unsafe, ok := convertArgType(rangefunc, t) + if !ok { + return name + } + if !unsafe { + return fmt.Sprintf("%v(%v)", to, name) + } + return fmt.Sprintf("*(*%v)(unsafe.Pointer(&%v))", to, name) + + case *types.Slice: + _, to, _, ok := convertArgType(rangefunc, t.Elem()) + if !ok { + return name + } + return fmt.Sprintf("*(*[]%v)(unsafe.Pointer(&%v))", to, name) + + default: + return name + } +} + +func convertReturn(rangefunc bool, t types.Type, name string) string { + switch t := t.(type) { + case *types.Named: + if t.Obj().Pkg() == nil || t.Obj().Pkg().Path() != "deedles.dev/xiter" { + return name + } + + tname, ok := strings.CutPrefix(t.Obj().Name(), "_") + if !ok { + return name + } + if rangefunc { + tname = "iter." + tname + } + + if t.TypeArgs().Len() == 0 { + return fmt.Sprintf("%v(%v)", tname, name) + } + + typeArgs := make([]string, 0, t.TypeArgs().Len()) + for _, arg := range listToSlice(t.TypeArgs()) { + typeArgs = append(typeArgs, convertType(rangefunc, false, arg)) + } + return fmt.Sprintf("%v[%v](%v)", tname, strings.Join(typeArgs, ","), name) + + default: + return name + } +} + +func load(ignore []string) []*types.Func { + config := packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo} + pkgs, err := packages.Load(&config, "deedles.dev/xiter") + if err != nil { + panic(err) + } + pkg := pkgs[0] + + var funcs []*types.Func + for _, def := range pkg.TypesInfo.Defs { + f, ok := def.(*types.Func) + if !ok { + continue + } + if slices.Contains(ignore, f.Name()) { + continue + } + if !namePattern.MatchString(f.Name()) { + continue + } + + funcs = append(funcs, f) + } + slices.SortFunc(funcs, func(f1, f2 *types.Func) int { return cmp.Compare(f1.Name(), f2.Name()) }) + + return funcs +} + +func write(name string, funcs []*types.Func, rangefunc bool) { + var buf bytes.Buffer + err := tmpl.Execute(&buf, map[string]any{"RangeFunc": rangefunc, "Funcs": funcs}) + if err != nil { + panic(err) + } + + b := buf.Bytes() + formatted, err := format.Source(b) + if err != nil { + slog.Error("format", "file", name, "err", err) + formatted = b + } + + file, err := os.Create(name) + if err != nil { + panic(err) + } + defer file.Close() + + _, err = file.Write(formatted) + if err != nil { + panic(err) + } +} + +func main() { + ignore := flag.String("ignore", "", "comma-separated list of declarations to ignore") + flag.Parse() + + funcs := load(strings.Split(*ignore, ",")) + write("gen_rangefunc.go", funcs, true) + write("gen_norangefunc.go", funcs, false) +} diff --git a/internal/gen/output.go.tmpl b/internal/gen/output.go.tmpl new file mode 100644 index 0000000..493b0c4 --- /dev/null +++ b/internal/gen/output.go.tmpl @@ -0,0 +1,36 @@ +// Code generated by internal/gen. DO NOT EDIT. + +//go:build {{if not .RangeFunc}}!{{end}}goexperiment.rangefunc + +package xiter + +import ( + "cmp" + "context" + "reflect" + "unsafe" + {{if .RangeFunc}}"iter"{{end}} +) + +{{range $func := .Funcs}} + func {{.Name | convertFuncName}}{{with .Type.TypeParams | typeParamSlice}}[ + {{- range .}} + {{- .}} {{.Constraint | convertType $.RangeFunc false}}, + {{- end -}} + ]{{end}}( + {{- range $i, $_ := .Type.Params | tupleSlice}} + {{- if ne $i 0}},{{end}}{{.Name}} {{.Type | convertType $.RangeFunc $func.Type.Variadic}} + {{- end -}} + ) ( + {{- range .Type.Results | tupleSlice}} + {{- .Name}} {{.Type | convertType $.RangeFunc false}}, + {{- end -}} + ) { + {{with .Type.Results}}{{range $i, $_ := . | tupleSlice}}{{if ne $i 0}},{{end}}_r{{$i}}{{end}} := {{end}}{{.Name}}( + {{- range $i, $p := .Type.Params | tupleSlice}} + {{- .Name | convertArg $.RangeFunc $p.Type}}{{if $func.Type.Variadic}}...{{end}}, + {{- end -}} + ) + {{with .Type.Results}}return {{range $i, $r := . | tupleSlice}}{{if ne $i 0}},{{end}}{{printf "_r%v" $i | convertReturn $.RangeFunc $r.Type}}{{end}}{{end}} + } +{{end}} diff --git a/oldzip_test.go b/oldzip_test.go index 3e6f523..68374fc 100644 --- a/oldzip_test.go +++ b/oldzip_test.go @@ -7,8 +7,8 @@ func BenchmarkOldZip(b *testing.B) { slice2 := []int{2, 3, 4, 5, 6} for i := 0; i < b.N; i++ { - s1 := OfSlice(slice1) - s2 := OfSlice(slice2) + s1 := _OfSlice(slice1) + s2 := _OfSlice(slice2) seq := oldZip(s1, s2) seq(func(v Zipped[int, int]) bool { return true @@ -27,7 +27,7 @@ func oldZipSend[T any](done <-chan struct{}, c chan<- T) func(v T) bool { } } -func oldZip[T1, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]] { +func oldZip[T1, T2 any](seq1 _Seq[T1], seq2 _Seq[T2]) _Seq[Zipped[T1, T2]] { done := make(chan struct{}) c1 := make(chan T1) diff --git a/reflect.go b/reflect.go index 4fd168e..6f2d0d6 100644 --- a/reflect.go +++ b/reflect.go @@ -5,11 +5,11 @@ import ( "reflect" ) -// OfValue returns a Seq2 that iterates over any iterable type using +// _OfValue returns a Seq2 that iterates over any iterable type using // reflection. If the type is one which only produces a single value // per iteration, such as a channel, the second value yielded each // iteration will just be reflect.Value{}. -func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { +func _OfValue(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { switch v.Kind() { case reflect.Array, reflect.Slice: return ofValueIndexable(v) @@ -34,7 +34,7 @@ func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { panic(fmt.Errorf("not rangeable type: %v", v.Type())) } -func ofValueIndexable(v reflect.Value) Seq2[reflect.Value, reflect.Value] { +func ofValueIndexable(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { return func(yield func(v1, v2 reflect.Value) bool) { for i := 0; i < v.Len(); i++ { if !yield(reflect.ValueOf(i), v.Index(i)) { @@ -45,14 +45,14 @@ func ofValueIndexable(v reflect.Value) Seq2[reflect.Value, reflect.Value] { } } -func ofValueString(v reflect.Value) Seq2[reflect.Value, reflect.Value] { - return FromPair(Map(ToPair(Enumerate(Runes(v.String()))), +func ofValueString(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { + return _FromPair(_Map(_ToPair(_Enumerate(_Runes(v.String()))), func(v Pair[int, rune]) Pair[reflect.Value, reflect.Value] { return P(reflect.ValueOf(v.V1), reflect.ValueOf(v.V2)) })) } -func ofValueChan(v reflect.Value) Seq2[reflect.Value, reflect.Value] { +func ofValueChan(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { var zero reflect.Value return func(yield func(v1, v2 reflect.Value) bool) { for { @@ -67,7 +67,7 @@ func ofValueChan(v reflect.Value) Seq2[reflect.Value, reflect.Value] { } } -func ofValueMap(v reflect.Value) Seq2[reflect.Value, reflect.Value] { +func ofValueMap(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { return func(yield func(v1, v2 reflect.Value) bool) { iter := v.MapRange() defer iter.Reset(reflect.Value{}) @@ -80,7 +80,7 @@ func ofValueMap(v reflect.Value) Seq2[reflect.Value, reflect.Value] { } } -func ofValuePointerToArray(v reflect.Value) Seq2[reflect.Value, reflect.Value] { +func ofValuePointerToArray(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { sv := v.Elem() if !sv.IsValid() { return func(func(v1, v2 reflect.Value) bool) { return } @@ -111,7 +111,7 @@ func isValueSeq(v reflect.Value) bool { return true } -func ofValueFunc(v reflect.Value) Seq2[reflect.Value, reflect.Value] { +func ofValueFunc(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { return func(yield func(v1, v2 reflect.Value) bool) { yv := reflect.MakeFunc(v.Type().In(0), func(vals []reflect.Value) []reflect.Value { v1, v2 := vals[0], reflect.Value{} @@ -125,7 +125,7 @@ func ofValueFunc(v reflect.Value) Seq2[reflect.Value, reflect.Value] { } } -func ofValueInt(v reflect.Value) Seq2[reflect.Value, reflect.Value] { +func ofValueInt(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { inc := func(v reflect.Value) reflect.Value { return reflect.ValueOf(v.Int() + 1) } if v.CanInt() && v.Int() < 0 { panic(fmt.Errorf("%v < 0", v.Int())) diff --git a/sink.go b/sink.go index e4cd53b..d28f840 100644 --- a/sink.go +++ b/sink.go @@ -5,8 +5,8 @@ import ( "context" ) -// AppendTo appends the values of seq to s, returning the new slice. -func AppendTo[T any, S ~[]T](seq Seq[T], s S) S { +// _AppendTo appends the values of seq to s, returning the new slice. +func _AppendTo[T any, S ~[]T](seq _Seq[T], s S) S { seq(func(v T) bool { s = append(s, v) return true @@ -14,20 +14,20 @@ func AppendTo[T any, S ~[]T](seq Seq[T], s S) S { return s } -// Collect returns a slice of the elements of seq. -func Collect[T any](seq Seq[T]) []T { - return CollectSize(seq, 0) +// _Collect returns a slice of the elements of seq. +func _Collect[T any](seq _Seq[T]) []T { + return _CollectSize(seq, 0) } -// CollectSize pre-allocates the slice being collected into to the +// _CollectSize pre-allocates the slice being collected into to the // given size. It is provided purely for convenience. -func CollectSize[T any](seq Seq[T], len int) []T { - return AppendTo(seq, make([]T, 0, len)) +func _CollectSize[T any](seq _Seq[T], len int) []T { + return _AppendTo(seq, make([]T, 0, len)) } -// Find returns the first value of seq for which f(value) returns +// _Find returns the first value of seq for which f(value) returns // true. -func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool) { +func _Find[T any](seq _Seq[T], f func(T) bool) (r T, ok bool) { seq(func(v T) bool { if !f(v) { return true @@ -39,33 +39,33 @@ func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool) { return r, ok } -// Contains returns true if v is an element of seq. -func Contains[T comparable](seq Seq[T], v T) bool { - _, ok := Find(seq, func(e T) bool { return v == e }) +// _Contains returns true if v is an element of seq. +func _Contains[T comparable](seq _Seq[T], v T) bool { + _, ok := _Find(seq, func(e T) bool { return v == e }) return ok } -// Any returns true if f(element) is true for any elements of seq. -func Any[T any](seq Seq[T], f func(T) bool) bool { - _, ok := Find(seq, f) +// _Any returns true if f(element) is true for any elements of seq. +func _Any[T any](seq _Seq[T], f func(T) bool) bool { + _, ok := _Find(seq, f) return ok } -// All returns true if f(element) is true for every element of seq. -func All[T any](seq Seq[T], f func(T) bool) bool { - return !Any(seq, f) +// _All returns true if f(element) is true for every element of seq. +func _All[T any](seq _Seq[T], f func(T) bool) bool { + return !_Any(seq, f) } -// Reduce calls reducer on each value of seq, passing it initial as +// _Reduce calls reducer on each value of seq, passing it initial as // its first argument on the first call and then the result of the // previous call for each call after that. It returns the final value // returned by reducer. // -// Reduce can be somewhat complicated to get the hang of, but very +// _Reduce can be somewhat complicated to get the hang of, but very // powerful. For example, a simple summation of values can be done as // -// sum := Reduce(seq, 0, func(total, v int) int { return total + v }) -func Reduce[T, R any](seq Seq[T], initial R, reducer func(R, T) R) R { +// sum := _Reduce(seq, 0, func(total, v int) int { return total + v }) +func _Reduce[T, R any](seq _Seq[T], initial R, reducer func(R, T) R) R { seq(func(v T) bool { initial = reducer(initial, v) return true @@ -73,10 +73,10 @@ func Reduce[T, R any](seq Seq[T], initial R, reducer func(R, T) R) R { return initial } -// Fold performs a [Reduce] but uses the first value yielded by seq +// _Fold performs a [Reduce] but uses the first value yielded by seq // instead of a provided initial value. If seq doesn't yield any // values, the zero value of T is returned. -func Fold[T any](seq Seq[T], reducer func(T, T) T) T { +func _Fold[T any](seq _Seq[T], reducer func(T, T) T) T { var prev T r := func(v1, v2 T) T { return v2 } seq(func(v T) bool { @@ -87,27 +87,27 @@ func Fold[T any](seq Seq[T], reducer func(T, T) T) T { return prev } -// Sum returns the values of seq added together in the order that they +// _Sum returns the values of seq added together in the order that they // are yielded. -func Sum[T Addable](seq Seq[T]) T { - return Fold(seq, func(total, v T) T { return total + v }) +func _Sum[T Addable](seq _Seq[T]) T { + return _Fold(seq, func(total, v T) T { return total + v }) } -// Product returns the values of seq multiplied together. It returns +// _Product returns the values of seq multiplied together. It returns // 1 if no values are yielded. -func Product[T Multiplyable](seq Seq[T]) T { - return Reduce(seq, 1, func(product, v T) T { return product * v }) +func _Product[T Multiplyable](seq _Seq[T]) T { + return _Reduce(seq, 1, func(product, v T) T { return product * v }) } -// IsSorted returns true if each element of seq is greater than or +// _IsSorted returns true if each element of seq is greater than or // equal to the previous one. -func IsSorted[T cmp.Ordered](seq Seq[T]) bool { - return IsSortedFunc(seq, cmp.Compare) +func _IsSorted[T cmp.Ordered](seq _Seq[T]) bool { + return _IsSortedFunc(seq, cmp.Compare) } -// IsSortedFunc is like [IsSorted] but uses a custom comparison +// _IsSortedFunc is like [IsSorted] but uses a custom comparison // function. -func IsSortedFunc[T any](seq Seq[T], compare func(T, T) int) bool { +func _IsSortedFunc[T any](seq _Seq[T], compare func(T, T) int) bool { var prev T c := func(T, T) int { return -1 } @@ -120,19 +120,19 @@ func IsSortedFunc[T any](seq Seq[T], compare func(T, T) int) bool { return sorted } -// Equal returns true if seq1 and seq2 are the same length and each +// _Equal returns true if seq1 and seq2 are the same length and each // element of each is equal to the element at the same point in the // sequence of the other. -func Equal[T cmp.Ordered](seq1, seq2 Seq[T]) bool { - return EqualFunc(seq1, seq2, func(v1, v2 T) bool { return v1 == v2 }) +func _Equal[T cmp.Ordered](seq1, seq2 _Seq[T]) bool { + return _EqualFunc(seq1, seq2, func(v1, v2 T) bool { return v1 == v2 }) } -// EqualFunc is like [Equal] but uses a custom comparison function to +// _EqualFunc is like [Equal] but uses a custom comparison function to // determine the equivalence of the elements of each sequence. -func EqualFunc[T1, T2 any](seq1 Seq[T1], seq2 Seq[T2], equal func(T1, T2) bool) bool { - p1, stop := Pull(seq1) +func _EqualFunc[T1, T2 any](seq1 _Seq[T1], seq2 _Seq[T2], equal func(T1, T2) bool) bool { + p1, stop := _Pull(seq1) defer stop() - p2, stop := Pull(seq2) + p2, stop := _Pull(seq2) defer stop() for { @@ -147,20 +147,20 @@ func EqualFunc[T1, T2 any](seq1 Seq[T1], seq2 Seq[T2], equal func(T1, T2) bool) } } -// Drain empties seq, discarding every single value and returning once +// _Drain empties seq, discarding every single value and returning once // it's finished. -func Drain[T any](seq Seq[T]) { +func _Drain[T any](seq _Seq[T]) { seq(func(T) bool { return true }) } -// CollectSplit is like [Collect], but for a SplitSeq. -func CollectSplit[T1, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { - return AppendSplitTo(seq, y1, y2) +// _CollectSplit is like [Collect], but for a SplitSeq. +func _CollectSplit[T1, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { + return _AppendSplitTo(seq, y1, y2) } -// AppendSplitTo collects the elements of seq by appending them to +// _AppendSplitTo collects the elements of seq by appending them to // existing slices. -func AppendSplitTo[T1, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { +func _AppendSplitTo[T1, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { seq( func(v T1) bool { s1 = append(s1, v) @@ -174,33 +174,33 @@ func AppendSplitTo[T1, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, [] return s1, s2 } -// Partition returns two slices, one containing all of the elements of +// _Partition returns two slices, one containing all of the elements of // seq for which f(element) is true and one containing all of those // for which it is false. -func Partition[T any](seq Seq[T], f func(T) bool) (true, false []T) { - return PartitionInto(seq, f, true, false) +func _Partition[T any](seq _Seq[T], f func(T) bool) (true, false []T) { + return _PartitionInto(seq, f, true, false) } -// PartitionInto performs a [Partition] by appending to two existing +// _PartitionInto performs a [Partition] by appending to two existing // slices. -func PartitionInto[T any](seq Seq[T], f func(T) bool, true, false []T) ([]T, []T) { - return AppendSplitTo(Split(seq, f), true, false) +func _PartitionInto[T any](seq _Seq[T], f func(T) bool, true, false []T) ([]T, []T) { + return _AppendSplitTo(_Split(seq, f), true, false) } -// Min returns the minimum element yielded by seq or the zero value if +// _Min returns the minimum element yielded by seq or the zero value if // seq doesn't yield anything. -func Min[T cmp.Ordered](seq Seq[T]) T { - return Fold(seq, func(v1, v2 T) T { return min(v1, v2) }) +func _Min[T cmp.Ordered](seq _Seq[T]) T { + return _Fold(seq, func(v1, v2 T) T { return min(v1, v2) }) } -// Max returns maximum element yielded by seq or the zero value if seq +// _Max returns maximum element yielded by seq or the zero value if seq // doesn't yield anything. -func Max[T cmp.Ordered](seq Seq[T]) T { - return Fold(seq, func(v1, v2 T) T { return max(v1, v2) }) +func _Max[T cmp.Ordered](seq _Seq[T]) T { + return _Fold(seq, func(v1, v2 T) T { return max(v1, v2) }) } -// FromPair converts a Seq of pairs to a two-value Seq. -func FromPair[T1, T2 any](seq Seq[Pair[T1, T2]]) Seq2[T1, T2] { +// _FromPair converts a Seq of pairs to a two-value Seq. +func _FromPair[T1, T2 any](seq _Seq[Pair[T1, T2]]) _Seq2[T1, T2] { return func(yield func(T1, T2) bool) { seq(func(v Pair[T1, T2]) bool { return yield(v.Split()) @@ -208,10 +208,10 @@ func FromPair[T1, T2 any](seq Seq[Pair[T1, T2]]) Seq2[T1, T2] { } } -// SendContext sends values from seq to c repeatedly until either the +// _SendContext sends values from seq to c repeatedly until either the // sequence ends or ctx is canceled. It blocks until one of those two // things happens. -func SendContext[T any](seq Seq[T], ctx context.Context, c chan<- T) { +func _SendContext[T any](seq _Seq[T], ctx context.Context, c chan<- T) { seq(func(v T) bool { select { case <-ctx.Done(): diff --git a/sink_test.go b/sink_test.go index 9936964..5c60296 100644 --- a/sink_test.go +++ b/sink_test.go @@ -7,50 +7,50 @@ import ( ) func TestFind(t *testing.T) { - s, _ := Find(Windows(Generate( + s, _ := _Find(_Windows(_Generate( 0, 1), 3), - func(win []int) bool { return Sum(OfSlice(win)) >= 100 }) + func(win []int) bool { return _Sum(_OfSlice(win)) >= 100 }) if [3]int(s) != [...]int{33, 34, 35} { t.Fatal(s) } } func TestContains(t *testing.T) { - c := Contains(Of(1, 2, 3), 2) + c := _Contains(_Of(1, 2, 3), 2) if !c { t.Fatal(c) } } func TestSum(t *testing.T) { - s := Sum(OfSlice([]string{"a", " ", "test"})) + s := _Sum(_OfSlice([]string{"a", " ", "test"})) if s != "a test" { t.Fatal(s) } } func TestProduct(t *testing.T) { - p := Product(Of(3, 2, -5)) + p := _Product(_Of(3, 2, -5)) if p != -30 { t.Fatal(p) } } func TestPartition(t *testing.T) { - s1, s2 := Partition(Of(1, 2, 3, 4, 5), func(v int) bool { return v%2 == 0 }) - if !Equal(OfSlice(s1), Of(2, 4)) { + s1, s2 := _Partition(_Of(1, 2, 3, 4, 5), func(v int) bool { return v%2 == 0 }) + if !_Equal(_OfSlice(s1), _Of(2, 4)) { t.Fatal(s1) } - if !Equal(OfSlice(s2), Of(1, 3, 5)) { + if !_Equal(_OfSlice(s2), _Of(1, 3, 5)) { t.Fatal(s2) } } func TestExtent(t *testing.T) { - s := Of(3, 2, 5, 1, 6, -2, 10) - min := Min(s) - max := Max(s) + s := _Of(3, 2, 5, 1, 6, -2, 10) + min := _Min(s) + max := _Max(s) if min != -2 { t.Fatal(min) } @@ -60,14 +60,14 @@ func TestExtent(t *testing.T) { } func TestAny(t *testing.T) { - r := Any(Of(2, 4, 6, 7), func(v int) bool { return v%2 != 0 }) + r := _Any(_Of(2, 4, 6, 7), func(v int) bool { return v%2 != 0 }) if !r { t.Fatal(r) } } func TestAll(t *testing.T) { - r := All(Of(2, 4, 6, 7), func(v int) bool { return v%2 == 0 }) + r := _All(_Of(2, 4, 6, 7), func(v int) bool { return v%2 == 0 }) if r { t.Fatal(r) } @@ -75,7 +75,7 @@ func TestAll(t *testing.T) { func TestSendContext(t *testing.T) { c := make(chan int, 3) - SendContext(Of(3, 2, 5), context.Background(), c) + _SendContext(_Of(3, 2, 5), context.Background(), c) s := []int{<-c, <-c, <-c} select { case v := <-c: @@ -95,9 +95,9 @@ func FuzzSendRecvContext(f *testing.F) { defer cancel() c := make(chan byte, len(data)) - SendContext(OfSlice(data), ctx, c) + _SendContext(_OfSlice(data), ctx, c) close(c) - s := Collect(RecvContext(ctx, c)) + s := _Collect(_RecvContext(ctx, c)) if !slices.Equal(data, s) { t.Fatal(s) } diff --git a/source.go b/source.go index 511f03d..b45aac0 100644 --- a/source.go +++ b/source.go @@ -7,11 +7,11 @@ import ( "unsafe" ) -// Generate returns a Seq that first yields start and then yields +// _Generate returns a Seq that first yields start and then yields // successive values by adding step to the previous continuously. The // returned Seq does not end. To limit it to a specific number of // returned elements, use [Limit]. -func Generate[T Addable](start, step T) Seq[T] { +func _Generate[T Addable](start, step T) _Seq[T] { return func(yield func(T) bool) { for { if !yield(start) { @@ -22,20 +22,20 @@ func Generate[T Addable](start, step T) Seq[T] { } } -// Of returns a Seq that yields the provided values. -func Of[T any](vals ...T) Seq[T] { - return OfSlice(vals) +// _Of returns a Seq that yields the provided values. +func _Of[T any](vals ...T) _Seq[T] { + return _OfSlice(vals) } -// OfSlice returns a Seq over the elements of s. It is equivalent to +// _OfSlice returns a Seq over the elements of s. It is equivalent to // range s with the index ignored. -func OfSlice[T any, S ~[]T](s S) Seq[T] { - return V2(OfSliceIndex(s)) +func _OfSlice[T any, S ~[]T](s S) _Seq[T] { + return _V2(_OfSliceIndex(s)) } -// OfSliceIndex returns a Seq over the elements of s. It is equivalent +// _OfSliceIndex returns a Seq over the elements of s. It is equivalent // to range s. -func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] { +func _OfSliceIndex[T any, S ~[]T](s S) _Seq2[int, T] { return func(yield func(int, T) bool) { for i, v := range s { if !yield(i, v) { @@ -46,8 +46,8 @@ func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] { } } -// Bytes returns a Seq over the bytes of s. -func Bytes(s string) Seq[byte] { +// _Bytes returns a Seq over the bytes of s. +func _Bytes(s string) _Seq[byte] { return func(yield func(byte) bool) { for i := 0; i < len(s); i++ { if !yield(s[i]) { @@ -58,8 +58,8 @@ func Bytes(s string) Seq[byte] { } } -// Runes returns a Seq over the runes of s. -func Runes[T ~[]byte | ~string](s T) Seq[rune] { +// _Runes returns a Seq over the runes of s. +func _Runes[T ~[]byte | ~string](s T) _Seq[rune] { return func(yield func(rune) bool) { b := unsafe.Slice(unsafe.StringData(*(*string)(unsafe.Pointer(&s))), len(s)) for len(b) > 0 { @@ -73,11 +73,11 @@ func Runes[T ~[]byte | ~string](s T) Seq[rune] { } } -// StringSplit returns an iterator over the substrings of s that are +// _StringSplit returns an iterator over the substrings of s that are // separated by sep. It behaves very similarly to [strings.Split]. -func StringSplit(s, sep string) Seq[string] { +func _StringSplit(s, sep string) _Seq[string] { if sep == "" { - return Map(Runes(s), func(c rune) string { return string(c) }) + return _Map(_Runes(s), func(c rune) string { return string(c) }) } return func(yield func(string) bool) { @@ -95,8 +95,8 @@ func StringSplit(s, sep string) Seq[string] { } } -// OfMap returns a Seq over the key-value pairs of m. -func OfMap[K comparable, V any, M ~map[K]V](m M) Seq2[K, V] { +// _OfMap returns a Seq over the key-value pairs of m. +func _OfMap[K comparable, V any, M ~map[K]V](m M) _Seq2[K, V] { return func(yield func(K, V) bool) { for k, v := range m { if !yield(k, v) { @@ -107,19 +107,19 @@ func OfMap[K comparable, V any, M ~map[K]V](m M) Seq2[K, V] { } } -// MapKeys returns a Seq over the keys of m. -func MapKeys[K comparable, V any, M ~map[K]V](m M) Seq[K] { - return V1(OfMap(m)) +// _MapKeys returns a Seq over the keys of m. +func _MapKeys[K comparable, V any, M ~map[K]V](m M) _Seq[K] { + return _V1(_OfMap(m)) } -// MapValues returns a Seq over the values of m. -func MapValues[K comparable, V any, M ~map[K]V](m M) Seq[V] { - return V2(OfMap(m)) +// _MapValues returns a Seq over the values of m. +func _MapValues[K comparable, V any, M ~map[K]V](m M) _Seq[V] { + return _V2(_OfMap(m)) } -// ToPair takes a two-value iterator and produces a single-value +// _ToPair takes a two-value iterator and produces a single-value // iterator of pairs. -func ToPair[T1, T2 any](seq Seq2[T1, T2]) Seq[Pair[T1, T2]] { +func _ToPair[T1, T2 any](seq _Seq2[T1, T2]) _Seq[Pair[T1, T2]] { return func(yield func(Pair[T1, T2]) bool) { seq(func(v1 T1, v2 T2) bool { return yield(P(v1, v2)) @@ -127,8 +127,8 @@ func ToPair[T1, T2 any](seq Seq2[T1, T2]) Seq[Pair[T1, T2]] { } } -// V1 returns a Seq which iterates over only the T1 elements of seq. -func V1[T1, T2 any](seq Seq2[T1, T2]) Seq[T1] { +// _V1 returns a Seq which iterates over only the T1 elements of seq. +func _V1[T1, T2 any](seq _Seq2[T1, T2]) _Seq[T1] { return func(yield func(T1) bool) { seq(func(v1 T1, v2 T2) bool { return yield(v1) @@ -136,8 +136,8 @@ func V1[T1, T2 any](seq Seq2[T1, T2]) Seq[T1] { } } -// V2 returns a Seq which iterates over only the T2 elements of seq. -func V2[T1, T2 any](seq Seq2[T1, T2]) Seq[T2] { +// _V2 returns a Seq which iterates over only the T2 elements of seq. +func _V2[T1, T2 any](seq _Seq2[T1, T2]) _Seq[T2] { return func(yield func(T2) bool) { seq(func(v1 T1, v2 T2) bool { return yield(v2) @@ -145,9 +145,9 @@ func V2[T1, T2 any](seq Seq2[T1, T2]) Seq[T2] { } } -// OfChan returns a Seq which yields values received from c. The +// _OfChan returns a Seq which yields values received from c. The // sequence ends when c is closed. It is equivalent to range c. -func OfChan[T any](c <-chan T) Seq[T] { +func _OfChan[T any](c <-chan T) _Seq[T] { return func(yield func(T) bool) { for v := range c { if !yield(v) { @@ -158,9 +158,9 @@ func OfChan[T any](c <-chan T) Seq[T] { } } -// RecvContext returns a Seq that receives from c continuously until +// _RecvContext returns a Seq that receives from c continuously until // either c is closed or the given context is canceled. -func RecvContext[T any](ctx context.Context, c <-chan T) Seq[T] { +func _RecvContext[T any](ctx context.Context, c <-chan T) _Seq[T] { return func(yield func(T) bool) { for { select { diff --git a/source_test.go b/source_test.go index 5cf110d..a3b2eca 100644 --- a/source_test.go +++ b/source_test.go @@ -8,21 +8,21 @@ import ( ) func TestBytes(t *testing.T) { - s := Collect(Bytes("テスト")) + s := _Collect(_Bytes("テスト")) if !slices.Equal(s, []byte("テスト")) { t.Fatal(s) } } func TestRunes(t *testing.T) { - s := Collect(Runes("これはテストです。")) + s := _Collect(_Runes("これはテストです。")) if [9]rune(s) != [9]rune([]rune("これはテストです。")) { t.Fatal(s) } } func TestMapEntries(t *testing.T) { - s := Collect(ToPair(OfMap(map[string]string{"this": "is", "a": "test"}))) + s := _Collect(_ToPair(_OfMap(map[string]string{"this": "is", "a": "test"}))) slices.SortFunc(s, func(e1, e2 Pair[string, string]) int { return cmp.Compare(e1.V1, e2.V2) }) if [2]Pair[string, string](s) != [...]Pair[string, string]{{"a", "test"}, {"this", "is"}} { t.Fatal(s) @@ -36,14 +36,14 @@ func TestRecvContext(t *testing.T) { c <- 5 close(c) - s := Collect(RecvContext(context.Background(), c)) + s := _Collect(_RecvContext(context.Background(), c)) if !slices.Equal(s, []int{3, 2, 5}) { t.Fatal(s) } } func TestStringSplit(t *testing.T) { - s := Collect(StringSplit("this is a test", " ")) + s := _Collect(_StringSplit("this is a test", " ")) if !slices.Equal(s, []string{"this", "is", "a", "test"}) { t.Fatal(s) } diff --git a/transform.go b/transform.go index d6ca43a..3f526a7 100644 --- a/transform.go +++ b/transform.go @@ -2,8 +2,8 @@ package xiter import "cmp" -// Map returns a Seq that yields the values of seq transformed via f. -func Map[T1, T2 any](seq Seq[T1], f func(T1) T2) Seq[T2] { +// _Map returns a Seq that yields the values of seq transformed via f. +func _Map[T1, T2 any](seq _Seq[T1], f func(T1) T2) _Seq[T2] { return func(yield func(T2) bool) { seq(func(v T1) bool { return yield(f(v)) @@ -11,9 +11,9 @@ func Map[T1, T2 any](seq Seq[T1], f func(T1) T2) Seq[T2] { } } -// Filter returns a Seq that yields only the values of seq for which +// _Filter returns a Seq that yields only the values of seq for which // f(value) returns true. -func Filter[T any](seq Seq[T], f func(T) bool) Seq[T] { +func _Filter[T any](seq _Seq[T], f func(T) bool) _Seq[T] { return func(yield func(T) bool) { seq(func(v T) bool { if !f(v) { @@ -24,9 +24,9 @@ func Filter[T any](seq Seq[T], f func(T) bool) Seq[T] { } } -// Skip returns a Seq that skips over the first n elements of seq and +// _Skip returns a Seq that skips over the first n elements of seq and // then yields the rest normally. -func Skip[T any](seq Seq[T], n int) Seq[T] { +func _Skip[T any](seq _Seq[T], n int) _Seq[T] { return func(yield func(T) bool) { seq(func(v T) bool { if n > 0 { @@ -38,7 +38,7 @@ func Skip[T any](seq Seq[T], n int) Seq[T] { } } -// Handle splits seq by calling f for any non-nil errors yielded by +// _Handle splits seq by calling f for any non-nil errors yielded by // seq. If f returns false, iteration stops. If an iteration's error // is nil or f returns true, the other value is yielded by the // returned Seq. @@ -46,7 +46,7 @@ func Skip[T any](seq Seq[T], n int) Seq[T] { // TODO: This is significantly less useful than it could be. For // example, there's no way to tell it to skip the yield but continue // iteration anyways. -func Handle[T any](seq Seq2[T, error], f func(error) bool) Seq[T] { +func _Handle[T any](seq _Seq2[T, error], f func(error) bool) _Seq[T] { return func(yield func(T) bool) { seq(func(v T, err error) bool { if err != nil { @@ -57,8 +57,8 @@ func Handle[T any](seq Seq2[T, error], f func(error) bool) Seq[T] { } } -// Limit returns a Seq that yields at most n values from seq. -func Limit[T any](seq Seq[T], n int) Seq[T] { +// _Limit returns a Seq that yields at most n values from seq. +func _Limit[T any](seq _Seq[T], n int) _Seq[T] { return func(yield func(T) bool) { seq(func(v T) bool { if !yield(v) { @@ -70,17 +70,17 @@ func Limit[T any](seq Seq[T], n int) Seq[T] { } } -// Concat creates a new Seq that yields the values of each of the +// _Concat creates a new Seq that yields the values of each of the // provided Seqs in turn. -func Concat[T any](seqs ...Seq[T]) Seq[T] { - return Flatten(OfSlice(seqs)) +func _Concat[T any](seqs ..._Seq[T]) _Seq[T] { + return _Flatten(_OfSlice(seqs)) } -// Flatten yields all of the elements of each Seq yielded from seq in +// _Flatten yields all of the elements of each Seq yielded from seq in // turn. -func Flatten[T any](seq Seq[Seq[T]]) Seq[T] { +func _Flatten[T any](seq _Seq[_Seq[T]]) _Seq[T] { return func(yield func(T) bool) { - seq(func(s Seq[T]) bool { + seq(func(s _Seq[T]) bool { s(yield) return true }) @@ -97,13 +97,13 @@ type Zipped[T1, T2 any] struct { OK2 bool } -// Zip returns a new Seq that yields the values of seq1 and seq2 +// _Zip returns a new Seq that yields the values of seq1 and seq2 // simultaneously. -func Zip[T1, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]] { +func _Zip[T1, T2 any](seq1 _Seq[T1], seq2 _Seq[T2]) _Seq[Zipped[T1, T2]] { return func(yield func(Zipped[T1, T2]) bool) { - p1, stop := Pull(seq1) + p1, stop := _Pull(seq1) defer stop() - p2, stop := Pull(seq2) + p2, stop := _Pull(seq2) defer stop() for { @@ -117,20 +117,20 @@ func Zip[T1, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]] { } } -// Merge returns a sequence that yields values from the ordered +// _Merge returns a sequence that yields values from the ordered // sequences seq1 and seq2 one at a time to produce a new ordered // sequence made up of all of the elements of both seq1 and seq2. -func Merge[T cmp.Ordered](seq1, seq2 Seq[T]) Seq[T] { - return MergeFunc(seq1, seq2, cmp.Compare) +func _Merge[T cmp.Ordered](seq1, seq2 _Seq[T]) _Seq[T] { + return _MergeFunc(seq1, seq2, cmp.Compare) } -// MergeFunc is like [Merge], but uses a custom comparison function +// _MergeFunc is like [Merge], but uses a custom comparison function // for determining the order of values. -func MergeFunc[T any](seq1, seq2 Seq[T], compare func(T, T) int) Seq[T] { +func _MergeFunc[T any](seq1, seq2 _Seq[T], compare func(T, T) int) _Seq[T] { return func(yield func(T) bool) { - p1, stop := Pull(seq1) + p1, stop := _Pull(seq1) defer stop() - p2, stop := Pull(seq2) + p2, stop := _Pull(seq2) defer stop() v1, ok1 := p1() @@ -165,10 +165,10 @@ func MergeFunc[T any](seq1, seq2 Seq[T], compare func(T, T) int) Seq[T] { } } -// Windows returns a slice over successive overlapping portions of +// _Windows returns a slice over successive overlapping portions of // size n of the values yielded by seq. In other words, // -// Windows(Generate(0, 1), 3) +// _Windows(Generate(0, 1), 3) // // will yield // @@ -180,7 +180,7 @@ func MergeFunc[T any](seq1, seq2 Seq[T], compare func(T, T) int) Seq[T] { // next, so it should not be held onto after each iteration has ended. // [Map] and [slices.Clone] may come in handy for dealing with // situations where this is necessary. -func Windows[T any](seq Seq[T], n int) Seq[[]T] { +func _Windows[T any](seq _Seq[T], n int) _Seq[[]T] { return func(yield func([]T) bool) { win := make([]T, 0, n) @@ -205,10 +205,10 @@ func Windows[T any](seq Seq[T], n int) Seq[[]T] { } } -// Chunks works just like [Windows] except that the yielded slices of +// _Chunks works just like [Windows] except that the yielded slices of // elements do not overlap. In other words, // -// Chunks(Generate(0, 1), 3) +// _Chunks(Generate(0, 1), 3) // // will yield // @@ -217,7 +217,7 @@ func Windows[T any](seq Seq[T], n int) Seq[[]T] { // [6, 7, 8] // // Like with Windows, the slice is reused between iterations. -func Chunks[T any](seq Seq[T], n int) Seq[[]T] { +func _Chunks[T any](seq _Seq[T], n int) _Seq[[]T] { return func(yield func([]T) bool) { win := make([]T, 0, n) @@ -247,10 +247,10 @@ func Chunks[T any](seq Seq[T], n int) Seq[[]T] { } } -// Split returns a SplitSeq which yields the values of seq for which +// _Split returns a SplitSeq which yields the values of seq for which // f(value) is true to its first yield function and the rest to its // second. -func Split[T any](seq Seq[T], f func(T) bool) SplitSeq[T, T] { +func _Split[T any](seq _Seq[T], f func(T) bool) SplitSeq[T, T] { return func(true, false func(T) bool) { seq(func(v T) bool { y := false @@ -262,9 +262,9 @@ func Split[T any](seq Seq[T], f func(T) bool) SplitSeq[T, T] { } } -// Split2 transforms a Seq2 into a SplitSeq. Every iteration of the +// _Split2 transforms a Seq2 into a SplitSeq. Every iteration of the // Seq2 yields both values via the SplitSeq. -func Split2[T1, T2 any](seq Seq2[T1, T2]) SplitSeq[T1, T2] { +func _Split2[T1, T2 any](seq _Seq2[T1, T2]) SplitSeq[T1, T2] { return func(y1 func(T1) bool, y2 func(T2) bool) { seq(func(v1 T1, v2 T2) bool { return y1(v1) && y2(v2) @@ -272,15 +272,15 @@ func Split2[T1, T2 any](seq Seq2[T1, T2]) SplitSeq[T1, T2] { } } -// Cache returns a Seq that can be iterated more than once. On the +// _Cache returns a Seq that can be iterated more than once. On the // first iteration, it yields the values from seq and caches them. On // subsequent iterations, it yields the cached values from the first // iteration. -func Cache[T any](seq Seq[T]) Seq[T] { +func _Cache[T any](seq _Seq[T]) _Seq[T] { var cache []T return func(yield func(T) bool) { if cache != nil { - OfSlice(cache)(yield) + _OfSlice(cache)(yield) return } @@ -292,9 +292,9 @@ func Cache[T any](seq Seq[T]) Seq[T] { } } -// Enumerate returns a Seq2 that counts the number of iterations of +// _Enumerate returns a Seq2 that counts the number of iterations of // seq as it yields elements from it, starting at 0. -func Enumerate[T any](seq Seq[T]) Seq2[int, T] { +func _Enumerate[T any](seq _Seq[T]) _Seq2[int, T] { return func(yield func(int, T) bool) { i := -1 seq(func(v T) bool { @@ -304,12 +304,12 @@ func Enumerate[T any](seq Seq[T]) Seq2[int, T] { } } -// Or yields all of the values from the first Seq which yields at +// _Or yields all of the values from the first Seq which yields at // least one value and then stops. -func Or[T any](seqs ...Seq[T]) Seq[T] { - ss := Filter(OfSlice(seqs), func(s Seq[T]) bool { return s != nil }) +func _Or[T any](seqs ..._Seq[T]) _Seq[T] { + ss := _Filter(_OfSlice(seqs), func(s _Seq[T]) bool { return s != nil }) return func(yield func(T) bool) { - ss(func(seq Seq[T]) bool { + ss(func(seq _Seq[T]) bool { cont := true seq(func(v T) bool { cont = false diff --git a/xiter.go b/xiter.go index 35907d3..bcddd45 100644 --- a/xiter.go +++ b/xiter.go @@ -1,25 +1,16 @@ // Package xiter provides iterator-related functionality compatible -// with, but not requiring, CL 510541. +// with, but not requiring, Go 1.22 and GOEXPERIMENT=rangefunc. package xiter import "sync" -// Seq represents an iterator over a sequence of values. When called, -// the passed yield function is called for each successive value. -// Returning false from yield causes the iterator to stop, equivalent -// to a break statement. The return value of the Seq function itself -// is completely ignored, but present to be compatible with the CL -// 510541 prototype. -type Seq[T any] func(yield func(T) bool) +//go:generate go run ./internal/gen // A SplitSeq is like a Seq but can yield via either of two functions. // It might not be useful, but is included anyways because it might // be. type SplitSeq[T1, T2 any] func(y1 func(T1) bool, y2 func(T2) bool) -// Seq2 represents a two-value iterator. -type Seq2[T1, T2 any] func(yield func(T1, T2) bool) - // Pair contains two values of arbitrary types. type Pair[T1, T2 any] struct { V1 T1 @@ -37,7 +28,7 @@ func (p Pair[T1, T2]) Split() (T1, T2) { return p.V1, p.V2 } -// Pull simulates a pull-iterator using Go's built-in concurrency +// _GoPull simulates a pull-iterator using Go's built-in concurrency // primitives in lieu of coroutines. It handles all synchronization // internally, so, despite running the iterator in a new thread, there // shouldn't be any data races, but there is some performance @@ -45,7 +36,7 @@ func (p Pair[T1, T2]) Split() (T1, T2) { // // The returned stop function must be called when the iterator is no // longer in use. -func Pull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { +func _GoPull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { next := make(chan struct{}) yield := make(chan T) diff --git a/xiter_norangefunc.go b/xiter_norangefunc.go new file mode 100644 index 0000000..573ae53 --- /dev/null +++ b/xiter_norangefunc.go @@ -0,0 +1,19 @@ +//go:build !goexperiment.rangefunc + +package xiter + +type _Seq[T any] func(yield func(T) bool) +type _Seq2[T1, T2 any] func(yield func(T1, T2) bool) + +// Seq represents an iterator over a sequence of values. When called, +// the passed yield function is called for each successive value. +// Returning false from yield causes the iterator to stop, equivalent +// to a break statement. +type Seq[T any] _Seq[T] + +// Seq2 represents a two-value iterator. +type Seq2[T1, T2 any] _Seq2[T1, T2] + +func _Pull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { + return _GoPull[T](seq) +} diff --git a/xiter_rangefunc.go b/xiter_rangefunc.go new file mode 100644 index 0000000..eda0271 --- /dev/null +++ b/xiter_rangefunc.go @@ -0,0 +1,18 @@ +//go:build goexperiment.rangefunc + +package xiter + +import "iter" + +// _Seq represents an iterator over a sequence of values. When called, +// the passed yield function is called for each successive value. +// Returning false from yield causes the iterator to stop, equivalent +// to a break statement. +type _Seq[T any] iter.Seq[T] // Type alias would be nice, but not supported for generic types. + +// _Seq2 represents a two-value iterator. +type _Seq2[T1, T2 any] iter.Seq2[T1, T2] + +func _Pull[T any](seq _Seq[T]) (iterator func() (T, bool), stop func()) { + return iter.Pull[T](iter.Seq[T](seq)) +}