From 107cc359d2008e2cd7a8dab8bbc60ca8cacdf6d6 Mon Sep 17 00:00:00 2001 From: David Chase Date: Tue, 12 Dec 2023 16:21:05 -0500 Subject: [PATCH 01/15] Update to make aware of GOEXPERIMENT=rangefunc iter package This will (attempt to) copy the types, and will use the coroutine version of "Pull" (which performs much better). The old goroutine version of Pull is renamed GoPull, and is used for Pull when the rangefunc GOEXPERIMENT is not set. --- xiter.go | 17 +++-------------- xiter_norangefunc.go | 16 ++++++++++++++++ xiter_rangefunc.go | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 xiter_norangefunc.go create mode 100644 xiter_rangefunc.go diff --git a/xiter.go b/xiter.go index 35907d3..e7d4d66 100644 --- a/xiter.go +++ b/xiter.go @@ -1,25 +1,14 @@ // 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) - // 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 +26,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 +34,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..479317c --- /dev/null +++ b/xiter_norangefunc.go @@ -0,0 +1,16 @@ +//go:build !goexperiment.rangefunc + +package xiter + +// 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] func(yield func(T) bool) + +// Seq2 represents a two-value iterator. +type Seq2[T1, T2 any] func(yield func(T1, T2) bool) + +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..98b5403 --- /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)) +} From fafd00ccda2d1c73915ed5c964c987050d6a9a41 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 00:22:45 -0500 Subject: [PATCH 02/15] internal/gen: add --- go.mod | 6 +++++- go.sum | 6 ++++++ internal/gen/gen.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 go.sum create mode 100644 internal/gen/gen.go 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..f8616d0 --- /dev/null +++ b/internal/gen/gen.go @@ -0,0 +1,34 @@ +package main + +import ( + "fmt" + "go/types" + "regexp" + + "golang.org/x/tools/go/packages" +) + +var ( + namePattern = regexp.MustCompile(`^_[A-Z]`) +) + +func main() { + config := packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo} + pkgs, err := packages.Load(&config, "deedles.dev/xiter") + if err != nil { + panic(err) + } + pkg := pkgs[0] + + for _, def := range pkg.TypesInfo.Defs { + f, ok := def.(*types.Func) + if !ok { + continue + } + if !namePattern.MatchString(f.Name()) { + continue + } + + fmt.Println(f) + } +} From df4f92e3a6e3b2bb46362ec9f8956da3b0bfbbef Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 00:32:13 -0500 Subject: [PATCH 03/15] xiter: rename pretty much everything to make it easier to do code generation --- oldzip_test.go | 6 +- reflect.go | 20 +++---- sink.go | 128 +++++++++++++++++++++---------------------- sink_test.go | 32 +++++------ source.go | 70 +++++++++++------------ source_test.go | 10 ++-- transform.go | 84 ++++++++++++++-------------- transform_test.go | 64 +++++++++++----------- xiter.go | 4 +- xiter_norangefunc.go | 9 ++- xiter_rangefunc.go | 12 ++-- 11 files changed, 221 insertions(+), 218 deletions(-) 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..35651c0 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,16 +120,16 @@ 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 { +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) @@ -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..34af815 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,9 +97,9 @@ 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) defer stop() @@ -117,16 +117,16 @@ 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) defer stop() @@ -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/transform_test.go b/transform_test.go index 71dd676..0c5591d 100644 --- a/transform_test.go +++ b/transform_test.go @@ -8,34 +8,34 @@ import ( ) func TestMap(t *testing.T) { - s := OfSlice([]int{1, 2, 3}) - n := Collect(Map(s, func(v int) float64 { return float64(v * 2) })) + s := _OfSlice([]int{1, 2, 3}) + n := _Collect(_Map(s, func(v int) float64 { return float64(v * 2) })) if [3]float64(n) != [...]float64{2, 4, 6} { t.Fatal(n) } } func TestFilter(t *testing.T) { - s := OfSlice([]int{1, 2, 3}) - n := Collect(Filter(s, func(v int) bool { return v%2 != 0 })) + s := _OfSlice([]int{1, 2, 3}) + n := _Collect(_Filter(s, func(v int) bool { return v%2 != 0 })) if [2]int(n) != [...]int{1, 3} { t.Fatal(n) } } func TestSkip(t *testing.T) { - s := Collect(Skip(Limit(Generate( + s := _Collect(_Skip(_Limit(_Generate( 0, 1), 3), 2), ) - if !Equal(OfSlice(s), Of(2)) { + if !_Equal(_OfSlice(s), _Of(2)) { t.Fatal(s) } } func TestLimit(t *testing.T) { - s := Collect(Limit(Generate( + s := _Collect(_Limit(_Generate( 0, 2), 3), ) @@ -45,16 +45,16 @@ func TestLimit(t *testing.T) { } func TestConcat(t *testing.T) { - s := Collect(Concat(OfSlice([]int{1, 2, 3}), OfSlice([]int{3, 2, 5}))) + s := _Collect(_Concat(_OfSlice([]int{1, 2, 3}), _OfSlice([]int{3, 2, 5}))) if [6]int(s) != [...]int{1, 2, 3, 3, 2, 5} { t.Fatal(s) } } func TestZip(t *testing.T) { - s1 := OfSlice([]int{1, 2, 3, 4, 5}) - s2 := OfSlice([]int{2, 3, 4, 5, 6}) - seq := Zip(s1, s2) + s1 := _OfSlice([]int{1, 2, 3, 4, 5}) + s2 := _OfSlice([]int{2, 3, 4, 5, 6}) + seq := _Zip(s1, s2) seq(func(v Zipped[int, int]) bool { if v.V2-v.V1 != 1 { t.Fatalf("unexpected values: %+v", v) @@ -68,9 +68,9 @@ func BenchmarkZip(b *testing.B) { slice2 := []int{2, 3, 4, 5, 6} for i := 0; i < b.N; i++ { - s1 := OfSlice(slice1) - s2 := OfSlice(slice2) - seq := Zip(s1, s2) + s1 := _OfSlice(slice1) + s2 := _OfSlice(slice2) + seq := _Zip(s1, s2) seq(func(v Zipped[int, int]) bool { return true }) @@ -78,38 +78,38 @@ func BenchmarkZip(b *testing.B) { } func TestIsSorted(t *testing.T) { - if IsSorted(OfSlice([]int{1, 2, 3, 2})) { + if _IsSorted(_OfSlice([]int{1, 2, 3, 2})) { t.Fatal("is not sorted") } - if !IsSorted(OfSlice([]int{1, 2, 3, 4, 5})) { + if !_IsSorted(_OfSlice([]int{1, 2, 3, 4, 5})) { t.Fatal("is sorted") } - if !IsSorted(OfSlice([]int{48, 48})) { + if !_IsSorted(_OfSlice([]int{48, 48})) { t.Fatal("is sorted") } } func TestMerge(t *testing.T) { - s1 := OfSlice([]int{2, 3, 5}) - s2 := OfSlice([]int{1, 2, 3, 4, 5}) - r := Collect(Merge(s1, s2)) + s1 := _OfSlice([]int{2, 3, 5}) + s2 := _OfSlice([]int{1, 2, 3, 4, 5}) + r := _Collect(_Merge(s1, s2)) if [8]int(r) != [...]int{1, 2, 2, 3, 3, 4, 5, 5} { t.Fatal(r) } } -func splitmerge[T cmp.Ordered](s []T) Seq[T] { +func splitmerge[T cmp.Ordered](s []T) _Seq[T] { if len(s) <= 1 { - return OfSlice(s) + return _OfSlice(s) } left := splitmerge(s[:len(s)/2]) right := splitmerge(s[len(s)/2:]) - return Merge(left, right) + return _Merge(left, right) } func mergesort[T cmp.Ordered](s []T) { - AppendTo(splitmerge(s), s[:0]) + _AppendTo(splitmerge(s), s[:0]) } func TestMergeSort(t *testing.T) { @@ -127,14 +127,14 @@ func FuzzMergeSort(f *testing.F) { slices.Sort(check) mergesort(s) - if !Equal(OfSlice(s), OfSlice(check)) { + if !_Equal(_OfSlice(s), _OfSlice(check)) { t.Fatal(s) } }) } func TestChunks(t *testing.T) { - s := Collect(Map(Chunks(OfSlice([]int{1, 2, 3, 4, 5}), + s := _Collect(_Map(_Chunks(_OfSlice([]int{1, 2, 3, 4, 5}), 2), slices.Clone), ) @@ -144,7 +144,7 @@ func TestChunks(t *testing.T) { } func TestSplit2(t *testing.T) { - s1, s2 := CollectSplit(Split2(FromPair(OfSlice([]Pair[int32, int64]{{1, 2}, {3, 4}, {5, 6}})))) + s1, s2 := _CollectSplit(_Split2(_FromPair(_OfSlice([]Pair[int32, int64]{{1, 2}, {3, 4}, {5, 6}})))) if !slices.Equal(s1, []int32{1, 3, 5}) { t.Fatal(s1) } @@ -160,24 +160,24 @@ func TestCache(t *testing.T) { i++ return } - seq := Cache(f) - if s := Collect(seq); !slices.Equal(s, []int{0}) { + seq := _Cache(f) + if s := _Collect(seq); !slices.Equal(s, []int{0}) { t.Fatal(s) } - if s := Collect(seq); !slices.Equal(s, []int{0}) { + if s := _Collect(seq); !slices.Equal(s, []int{0}) { t.Fatal(s) } } func TestEnumerate(t *testing.T) { - s := Collect(ToPair(Enumerate(Limit(Generate(0, 2), 3)))) + s := _Collect(_ToPair(_Enumerate(_Limit(_Generate(0, 2), 3)))) if !slices.Equal(s, []Pair[int, int]{{0, 0}, {1, 2}, {2, 4}}) { t.Fatal(s) } } func TestOr(t *testing.T) { - s := Collect(Or(Of[int](), nil, Of(1, 2, 3), Of(4, 5, 6))) + s := _Collect(_Or(_Of[int](), nil, _Of(1, 2, 3), _Of(4, 5, 6))) if !slices.Equal(s, []int{1, 2, 3}) { t.Fatal(s) } diff --git a/xiter.go b/xiter.go index e7d4d66..57f4856 100644 --- a/xiter.go +++ b/xiter.go @@ -26,7 +26,7 @@ func (p Pair[T1, T2]) Split() (T1, T2) { return p.V1, p.V2 } -// GoPull 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 @@ -34,7 +34,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 GoPull[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 index 479317c..1b95571 100644 --- a/xiter_norangefunc.go +++ b/xiter_norangefunc.go @@ -2,15 +2,18 @@ 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] func(yield func(T) bool) +type Seq[T any] _Seq[T] // Seq2 represents a two-value iterator. -type Seq2[T1, T2 any] func(yield func(T1, T2) bool) +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) + return _GoPull[T](_Seq[T](seq)) } diff --git a/xiter_rangefunc.go b/xiter_rangefunc.go index 98b5403..c1872d1 100644 --- a/xiter_rangefunc.go +++ b/xiter_rangefunc.go @@ -4,15 +4,15 @@ package xiter import "iter" -// Seq represents an iterator over a sequence of values. When called, +// _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. +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] +// _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)) +func Pull[T any](seq iter.Seq[T]) (iterator func() (T, bool), stop func()) { + return iter.Pull[T](seq) } From 633a6e5860de66b127cbf3eacb67e039c6fcaca7 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 00:56:54 -0500 Subject: [PATCH 04/15] internal/gen: output files that don't quite work yet --- internal/gen/gen.go | 54 ++++++++++++++++++++++++++++++++++--- internal/gen/output.go.tmpl | 9 +++++++ 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 internal/gen/output.go.tmpl diff --git a/internal/gen/gen.go b/internal/gen/gen.go index f8616d0..9ecc969 100644 --- a/internal/gen/gen.go +++ b/internal/gen/gen.go @@ -1,18 +1,32 @@ package main import ( - "fmt" + "bytes" + _ "embed" + "go/format" "go/types" + "os" "regexp" + "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{"convertName": convertName} ) -func main() { +func convertName(name string) string { + return strings.TrimPrefix(name, "_") +} + +func load() []*types.Func { config := packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo} pkgs, err := packages.Load(&config, "deedles.dev/xiter") if err != nil { @@ -20,6 +34,7 @@ func main() { } pkg := pkgs[0] + var funcs []*types.Func for _, def := range pkg.TypesInfo.Defs { f, ok := def.(*types.Func) if !ok { @@ -29,6 +44,39 @@ func main() { continue } - fmt.Println(f) + funcs = append(funcs, f) } + + 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() + b, err = format.Source(b) + if err != nil { + panic(err) + } + + file, err := os.Create(name) + if err != nil { + panic(err) + } + defer file.Close() + + _, err = file.Write(b) + if err != nil { + panic(err) + } +} + +func main() { + funcs := load() + 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..8273b91 --- /dev/null +++ b/internal/gen/output.go.tmpl @@ -0,0 +1,9 @@ +// Code generated by internal/gen. DO NOT EDIT. + +//go:build {{if not .RangeFunc}}!{{end}}rangefunc + +package xiter + +{{range $func := .Funcs}} + func {{$func.Name | convertName}}() {} +{{end}} From 215472cbd6c57efdbecc5faeae34d77899eb42d4 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 00:57:11 -0500 Subject: [PATCH 05/15] xiter: generate files --- gen_norangefunc.go | 121 +++++++++++++++++++++++++++++++++++++++++++++ gen_rangefunc.go | 121 +++++++++++++++++++++++++++++++++++++++++++++ xiter.go | 2 + 3 files changed, 244 insertions(+) create mode 100644 gen_norangefunc.go create mode 100644 gen_rangefunc.go diff --git a/gen_norangefunc.go b/gen_norangefunc.go new file mode 100644 index 0000000..787d465 --- /dev/null +++ b/gen_norangefunc.go @@ -0,0 +1,121 @@ +// Code generated by internal/gen. DO NOT EDIT. + +//go:build !rangefunc + +package xiter + +func MapKeys() {} + +func Limit() {} + +func IsSorted() {} + +func Windows() {} + +func Merge() {} + +func CollectSplit() {} + +func OfValue() {} + +func Max() {} + +func Skip() {} + +func AppendSplitTo() {} + +func Handle() {} + +func Concat() {} + +func StringSplit() {} + +func Fold() {} + +func CollectSize() {} + +func Product() {} + +func RecvContext() {} + +func OfMap() {} + +func Or() {} + +func Reduce() {} + +func Runes() {} + +func PartitionInto() {} + +func Bytes() {} + +func Sum() {} + +func Min() {} + +func AppendTo() {} + +func Collect() {} + +func OfSliceIndex() {} + +func Any() {} + +func All() {} + +func IsSortedFunc() {} + +func V2() {} + +func Equal() {} + +func ToPair() {} + +func Flatten() {} + +func V1() {} + +func Partition() {} + +func Find() {} + +func OfSlice() {} + +func Map() {} + +func Generate() {} + +func EqualFunc() {} + +func Of() {} + +func Zip() {} + +func GoPull() {} + +func MergeFunc() {} + +func Split() {} + +func Drain() {} + +func OfChan() {} + +func Split2() {} + +func MapValues() {} + +func FromPair() {} + +func Contains() {} + +func Chunks() {} + +func Enumerate() {} + +func Filter() {} + +func SendContext() {} + +func Cache() {} diff --git a/gen_rangefunc.go b/gen_rangefunc.go new file mode 100644 index 0000000..a3a044a --- /dev/null +++ b/gen_rangefunc.go @@ -0,0 +1,121 @@ +// Code generated by internal/gen. DO NOT EDIT. + +//go:build rangefunc + +package xiter + +func MapKeys() {} + +func Limit() {} + +func IsSorted() {} + +func Windows() {} + +func Merge() {} + +func CollectSplit() {} + +func OfValue() {} + +func Max() {} + +func Skip() {} + +func AppendSplitTo() {} + +func Handle() {} + +func Concat() {} + +func StringSplit() {} + +func Fold() {} + +func CollectSize() {} + +func Product() {} + +func RecvContext() {} + +func OfMap() {} + +func Or() {} + +func Reduce() {} + +func Runes() {} + +func PartitionInto() {} + +func Bytes() {} + +func Sum() {} + +func Min() {} + +func AppendTo() {} + +func Collect() {} + +func OfSliceIndex() {} + +func Any() {} + +func All() {} + +func IsSortedFunc() {} + +func V2() {} + +func Equal() {} + +func ToPair() {} + +func Flatten() {} + +func V1() {} + +func Partition() {} + +func Find() {} + +func OfSlice() {} + +func Map() {} + +func Generate() {} + +func EqualFunc() {} + +func Of() {} + +func Zip() {} + +func GoPull() {} + +func MergeFunc() {} + +func Split() {} + +func Drain() {} + +func OfChan() {} + +func Split2() {} + +func MapValues() {} + +func FromPair() {} + +func Contains() {} + +func Chunks() {} + +func Enumerate() {} + +func Filter() {} + +func SendContext() {} + +func Cache() {} diff --git a/xiter.go b/xiter.go index 57f4856..bcddd45 100644 --- a/xiter.go +++ b/xiter.go @@ -4,6 +4,8 @@ package xiter import "sync" +//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. From 3db7d28747f607a17df231341cf511f34e6eefd8 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 13:47:21 -0500 Subject: [PATCH 06/15] internal/gen: a bunch more implementation of code generation --- internal/gen/gen.go | 69 ++++++++++++++++++++++++++++++++++--- internal/gen/output.go.tmpl | 24 +++++++++++-- 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/internal/gen/gen.go b/internal/gen/gen.go index 9ecc969..7933925 100644 --- a/internal/gen/gen.go +++ b/internal/gen/gen.go @@ -3,8 +3,10 @@ package main import ( "bytes" _ "embed" + "fmt" "go/format" "go/types" + "log/slog" "os" "regexp" "strings" @@ -19,13 +21,71 @@ var ( //go:embed output.go.tmpl outputTemplate string tmpl = template.Must(template.New("output").Funcs(funcMap).Parse(outputTemplate)) - funcMap = map[string]any{"convertName": convertName} + funcMap = map[string]any{ + "convertName": convertName, + "typeParamSlice": listToSlice[*types.TypeParam], + "tupleSlice": listToSlice[*types.Var], + "convertType": convertType, + } ) func convertName(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, 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() + "." + } + + if t.TypeArgs().Len() == 0 { + return pkg + t.Obj().Name() + } + + typeArgs := make([]string, 0, t.TypeArgs().Len()) + for _, arg := range listToSlice(t.TypeArgs()) { + typeArgs = append(typeArgs, convertType(rangefunc, arg)) + } + return fmt.Sprintf("%v%v[%v]", pkg, t.Obj().Name(), strings.Join(typeArgs, ",")) + + case *types.Slice: + return fmt.Sprintf("[]%v", convertType(rangefunc, t.Elem())) + + case *types.Interface, *types.Basic, *types.TypeParam, *types.Signature, *types.Chan: + return t.String() + + default: + return fmt.Sprintf("\"%T\"", t) + } +} + +func join[T any](sep string, s []T) string { + var i string + var buf strings.Builder + for _, v := range s { + fmt.Fprintf(&buf, "%v%v", i, v) + i = sep + } + return buf.String() +} + func load() []*types.Func { config := packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo} pkgs, err := packages.Load(&config, "deedles.dev/xiter") @@ -58,9 +118,10 @@ func write(name string, funcs []*types.Func, rangefunc bool) { } b := buf.Bytes() - b, err = format.Source(b) + formatted, err := format.Source(b) if err != nil { - panic(err) + slog.Error("format", "file", name, "err", err) + formatted = b } file, err := os.Create(name) @@ -69,7 +130,7 @@ func write(name string, funcs []*types.Func, rangefunc bool) { } defer file.Close() - _, err = file.Write(b) + _, err = file.Write(formatted) if err != nil { panic(err) } diff --git a/internal/gen/output.go.tmpl b/internal/gen/output.go.tmpl index 8273b91..24f2e81 100644 --- a/internal/gen/output.go.tmpl +++ b/internal/gen/output.go.tmpl @@ -4,6 +4,26 @@ package xiter -{{range $func := .Funcs}} - func {{$func.Name | convertName}}() {} +import ( + "cmp" + "context" + "reflect" +) + +{{range .Funcs}} + func {{.Name | convertName}}{{with .Type.TypeParams | typeParamSlice}}[ + {{- range .}} + {{- .}} {{.Constraint | convertType $.RangeFunc}}, + {{- end -}} + ]{{end}}( + {{- range .Type.Params | tupleSlice}} + {{- .Name}} {{.Type | convertType $.RangeFunc}}, + {{- end -}} + ) ( + {{- range .Type.Results | tupleSlice}} + {{- .Name}} {{.Type | convertType $.RangeFunc}}, + {{- end -}} + ) { + panic("Not implemented.") + } {{end}} From cf7ce9b30e768a618bbb086b937e28d6ddeeee09 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 13:47:39 -0500 Subject: [PATCH 07/15] xiter: fix `Pull()` --- gen_norangefunc.go | 242 ++++++++++++++++++++++++++++++++----------- gen_rangefunc.go | 242 ++++++++++++++++++++++++++++++++----------- sink.go | 4 +- transform.go | 8 +- xiter_norangefunc.go | 4 +- xiter_rangefunc.go | 4 +- 6 files changed, 378 insertions(+), 126 deletions(-) diff --git a/gen_norangefunc.go b/gen_norangefunc.go index 787d465..c34a275 100644 --- a/gen_norangefunc.go +++ b/gen_norangefunc.go @@ -4,118 +4,244 @@ package xiter -func MapKeys() {} +import ( + "cmp" + "context" + "reflect" +) -func Limit() {} +func Find[T any](seq _Seq[T], f func(T) bool) (r T, ok bool) { + panic("Not implemented.") +} -func IsSorted() {} +func Chunks[T any](seq _Seq[T], n int) _Seq[[]T] { + panic("Not implemented.") +} -func Windows() {} +func All[T any](seq _Seq[T], f func(T) bool) bool { + panic("Not implemented.") +} -func Merge() {} +func OfMap[K comparable, V any, M ~map[K]V](m M) _Seq2[K, V] { + panic("Not implemented.") +} -func CollectSplit() {} +func Enumerate[T any](seq _Seq[T]) _Seq2[int, T] { + panic("Not implemented.") +} -func OfValue() {} +func Concat[T any](seqs []_Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Max() {} +func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { + panic("Not implemented.") +} -func Skip() {} +func CollectSize[T any](seq _Seq[T], len int) []T { + panic("Not implemented.") +} -func AppendSplitTo() {} +func AppendTo[T any, S ~[]T](seq _Seq[T], s S) S { + panic("Not implemented.") +} -func Handle() {} +func OfSlice[T any, S ~[]T](s S) _Seq[T] { + panic("Not implemented.") +} -func Concat() {} +func Reduce[T any, R any](seq _Seq[T], initial R, reducer func(R, T) R) R { + panic("Not implemented.") +} -func StringSplit() {} +func Windows[T any](seq _Seq[T], n int) _Seq[[]T] { + panic("Not implemented.") +} -func Fold() {} +func Skip[T any](seq _Seq[T], n int) _Seq[T] { + panic("Not implemented.") +} -func CollectSize() {} +func PartitionInto[T any](seq _Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { + panic("Not implemented.") +} -func Product() {} +func SendContext[T any](seq _Seq[T], ctx context.Context, c chan<- T) { + panic("Not implemented.") +} -func RecvContext() {} +func Split[T any](seq _Seq[T], f func(T) bool) SplitSeq[T, T] { + panic("Not implemented.") +} -func OfMap() {} +func ToPair[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[Pair[T1, T2]] { + panic("Not implemented.") +} -func Or() {} +func Merge[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Reduce() {} +func MergeFunc[T any](seq1 _Seq[T], seq2 _Seq[T], compare func(T, T) int) _Seq[T] { + panic("Not implemented.") +} -func Runes() {} +func Sum[T Addable](seq _Seq[T]) T { + panic("Not implemented.") +} -func PartitionInto() {} +func Equal[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) bool { + panic("Not implemented.") +} -func Bytes() {} +func Or[T any](seqs []_Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Sum() {} +func OfChan[T any](c <-chan T) _Seq[T] { + panic("Not implemented.") +} -func Min() {} +func Map[T1 any, T2 any](seq _Seq[T1], f func(T1) T2) _Seq[T2] { + panic("Not implemented.") +} -func AppendTo() {} +func Contains[T comparable](seq _Seq[T], v T) bool { + panic("Not implemented.") +} -func Collect() {} +func Split2[T1 any, T2 any](seq _Seq2[T1, T2]) SplitSeq[T1, T2] { + panic("Not implemented.") +} -func OfSliceIndex() {} +func IsSortedFunc[T any](seq _Seq[T], compare func(T, T) int) bool { + panic("Not implemented.") +} -func Any() {} +func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { + panic("Not implemented.") +} -func All() {} +func StringSplit(s string, sep string) _Seq[string] { + panic("Not implemented.") +} -func IsSortedFunc() {} +func GoPull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { + panic("Not implemented.") +} -func V2() {} +func Handle[T any](seq _Seq2[T, error], f func(error) bool) _Seq[T] { + panic("Not implemented.") +} -func Equal() {} +func MapKeys[K comparable, V any, M ~map[K]V](m M) _Seq[K] { + panic("Not implemented.") +} -func ToPair() {} +func OfValue(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { + panic("Not implemented.") +} -func Flatten() {} +func Any[T any](seq _Seq[T], f func(T) bool) bool { + panic("Not implemented.") +} -func V1() {} +func Limit[T any](seq _Seq[T], n int) _Seq[T] { + panic("Not implemented.") +} -func Partition() {} +func Bytes(s string) _Seq[byte] { + panic("Not implemented.") +} -func Find() {} +func Runes[T ~[]byte | ~string](s T) _Seq[rune] { + panic("Not implemented.") +} -func OfSlice() {} +func V1[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T1] { + panic("Not implemented.") +} -func Map() {} +func Drain[T any](seq _Seq[T]) { + panic("Not implemented.") +} -func Generate() {} +func MapValues[K comparable, V any, M ~map[K]V](m M) _Seq[V] { + panic("Not implemented.") +} -func EqualFunc() {} +func IsSorted[T cmp.Ordered](seq _Seq[T]) bool { + panic("Not implemented.") +} -func Of() {} +func Partition[T any](seq _Seq[T], f func(T) bool) (true []T, false []T) { + panic("Not implemented.") +} -func Zip() {} +func Max[T cmp.Ordered](seq _Seq[T]) T { + panic("Not implemented.") +} -func GoPull() {} +func Fold[T any](seq _Seq[T], reducer func(T, T) T) T { + panic("Not implemented.") +} -func MergeFunc() {} +func EqualFunc[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2], equal func(T1, T2) bool) bool { + panic("Not implemented.") +} -func Split() {} +func Flatten[T any](seq _Seq[_Seq[T]]) _Seq[T] { + panic("Not implemented.") +} -func Drain() {} +func FromPair[T1 any, T2 any](seq _Seq[Pair[T1, T2]]) _Seq2[T1, T2] { + panic("Not implemented.") +} -func OfChan() {} +func Filter[T any](seq _Seq[T], f func(T) bool) _Seq[T] { + panic("Not implemented.") +} -func Split2() {} +func RecvContext[T any](ctx context.Context, c <-chan T) _Seq[T] { + panic("Not implemented.") +} -func MapValues() {} +func Generate[T Addable](start T, step T) _Seq[T] { + panic("Not implemented.") +} -func FromPair() {} +func Min[T cmp.Ordered](seq _Seq[T]) T { + panic("Not implemented.") +} -func Contains() {} +func V2[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T2] { + panic("Not implemented.") +} -func Chunks() {} +func Product[T Multiplyable](seq _Seq[T]) T { + panic("Not implemented.") +} -func Enumerate() {} +func Cache[T any](seq _Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Filter() {} +func Collect[T any](seq _Seq[T]) []T { + panic("Not implemented.") +} -func SendContext() {} +func Of[T any](vals []T) _Seq[T] { + panic("Not implemented.") +} -func Cache() {} +func Pull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { + panic("Not implemented.") +} + +func OfSliceIndex[T any, S ~[]T](s S) _Seq2[int, T] { + panic("Not implemented.") +} + +func Zip[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2]) _Seq[Zipped[T1, T2]] { + panic("Not implemented.") +} diff --git a/gen_rangefunc.go b/gen_rangefunc.go index a3a044a..8149c1f 100644 --- a/gen_rangefunc.go +++ b/gen_rangefunc.go @@ -4,118 +4,244 @@ package xiter -func MapKeys() {} +import ( + "cmp" + "context" + "reflect" +) -func Limit() {} +func Find[T any](seq _Seq[T], f func(T) bool) (r T, ok bool) { + panic("Not implemented.") +} -func IsSorted() {} +func Chunks[T any](seq _Seq[T], n int) _Seq[[]T] { + panic("Not implemented.") +} -func Windows() {} +func All[T any](seq _Seq[T], f func(T) bool) bool { + panic("Not implemented.") +} -func Merge() {} +func OfMap[K comparable, V any, M ~map[K]V](m M) _Seq2[K, V] { + panic("Not implemented.") +} -func CollectSplit() {} +func Enumerate[T any](seq _Seq[T]) _Seq2[int, T] { + panic("Not implemented.") +} -func OfValue() {} +func Concat[T any](seqs []_Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Max() {} +func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { + panic("Not implemented.") +} -func Skip() {} +func CollectSize[T any](seq _Seq[T], len int) []T { + panic("Not implemented.") +} -func AppendSplitTo() {} +func AppendTo[T any, S ~[]T](seq _Seq[T], s S) S { + panic("Not implemented.") +} -func Handle() {} +func OfSlice[T any, S ~[]T](s S) _Seq[T] { + panic("Not implemented.") +} -func Concat() {} +func Reduce[T any, R any](seq _Seq[T], initial R, reducer func(R, T) R) R { + panic("Not implemented.") +} -func StringSplit() {} +func Windows[T any](seq _Seq[T], n int) _Seq[[]T] { + panic("Not implemented.") +} -func Fold() {} +func Skip[T any](seq _Seq[T], n int) _Seq[T] { + panic("Not implemented.") +} -func CollectSize() {} +func PartitionInto[T any](seq _Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { + panic("Not implemented.") +} -func Product() {} +func SendContext[T any](seq _Seq[T], ctx context.Context, c chan<- T) { + panic("Not implemented.") +} -func RecvContext() {} +func Split[T any](seq _Seq[T], f func(T) bool) SplitSeq[T, T] { + panic("Not implemented.") +} -func OfMap() {} +func ToPair[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[Pair[T1, T2]] { + panic("Not implemented.") +} -func Or() {} +func Merge[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Reduce() {} +func MergeFunc[T any](seq1 _Seq[T], seq2 _Seq[T], compare func(T, T) int) _Seq[T] { + panic("Not implemented.") +} -func Runes() {} +func Sum[T Addable](seq _Seq[T]) T { + panic("Not implemented.") +} -func PartitionInto() {} +func Equal[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) bool { + panic("Not implemented.") +} -func Bytes() {} +func Or[T any](seqs []_Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Sum() {} +func OfChan[T any](c <-chan T) _Seq[T] { + panic("Not implemented.") +} -func Min() {} +func Map[T1 any, T2 any](seq _Seq[T1], f func(T1) T2) _Seq[T2] { + panic("Not implemented.") +} -func AppendTo() {} +func Contains[T comparable](seq _Seq[T], v T) bool { + panic("Not implemented.") +} -func Collect() {} +func Split2[T1 any, T2 any](seq _Seq2[T1, T2]) SplitSeq[T1, T2] { + panic("Not implemented.") +} -func OfSliceIndex() {} +func IsSortedFunc[T any](seq _Seq[T], compare func(T, T) int) bool { + panic("Not implemented.") +} -func Any() {} +func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { + panic("Not implemented.") +} -func All() {} +func StringSplit(s string, sep string) _Seq[string] { + panic("Not implemented.") +} -func IsSortedFunc() {} +func GoPull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { + panic("Not implemented.") +} -func V2() {} +func Handle[T any](seq _Seq2[T, error], f func(error) bool) _Seq[T] { + panic("Not implemented.") +} -func Equal() {} +func MapKeys[K comparable, V any, M ~map[K]V](m M) _Seq[K] { + panic("Not implemented.") +} -func ToPair() {} +func OfValue(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { + panic("Not implemented.") +} -func Flatten() {} +func Any[T any](seq _Seq[T], f func(T) bool) bool { + panic("Not implemented.") +} -func V1() {} +func Limit[T any](seq _Seq[T], n int) _Seq[T] { + panic("Not implemented.") +} -func Partition() {} +func Bytes(s string) _Seq[byte] { + panic("Not implemented.") +} -func Find() {} +func Runes[T ~[]byte | ~string](s T) _Seq[rune] { + panic("Not implemented.") +} -func OfSlice() {} +func V1[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T1] { + panic("Not implemented.") +} -func Map() {} +func Drain[T any](seq _Seq[T]) { + panic("Not implemented.") +} -func Generate() {} +func MapValues[K comparable, V any, M ~map[K]V](m M) _Seq[V] { + panic("Not implemented.") +} -func EqualFunc() {} +func IsSorted[T cmp.Ordered](seq _Seq[T]) bool { + panic("Not implemented.") +} -func Of() {} +func Partition[T any](seq _Seq[T], f func(T) bool) (true []T, false []T) { + panic("Not implemented.") +} -func Zip() {} +func Max[T cmp.Ordered](seq _Seq[T]) T { + panic("Not implemented.") +} -func GoPull() {} +func Fold[T any](seq _Seq[T], reducer func(T, T) T) T { + panic("Not implemented.") +} -func MergeFunc() {} +func EqualFunc[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2], equal func(T1, T2) bool) bool { + panic("Not implemented.") +} -func Split() {} +func Flatten[T any](seq _Seq[_Seq[T]]) _Seq[T] { + panic("Not implemented.") +} -func Drain() {} +func FromPair[T1 any, T2 any](seq _Seq[Pair[T1, T2]]) _Seq2[T1, T2] { + panic("Not implemented.") +} -func OfChan() {} +func Filter[T any](seq _Seq[T], f func(T) bool) _Seq[T] { + panic("Not implemented.") +} -func Split2() {} +func RecvContext[T any](ctx context.Context, c <-chan T) _Seq[T] { + panic("Not implemented.") +} -func MapValues() {} +func Generate[T Addable](start T, step T) _Seq[T] { + panic("Not implemented.") +} -func FromPair() {} +func Min[T cmp.Ordered](seq _Seq[T]) T { + panic("Not implemented.") +} -func Contains() {} +func V2[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T2] { + panic("Not implemented.") +} -func Chunks() {} +func Product[T Multiplyable](seq _Seq[T]) T { + panic("Not implemented.") +} -func Enumerate() {} +func Cache[T any](seq _Seq[T]) _Seq[T] { + panic("Not implemented.") +} -func Filter() {} +func Collect[T any](seq _Seq[T]) []T { + panic("Not implemented.") +} -func SendContext() {} +func Of[T any](vals []T) _Seq[T] { + panic("Not implemented.") +} -func Cache() {} +func Pull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { + panic("Not implemented.") +} + +func OfSliceIndex[T any, S ~[]T](s S) _Seq2[int, T] { + panic("Not implemented.") +} + +func Zip[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2]) _Seq[Zipped[T1, T2]] { + panic("Not implemented.") +} diff --git a/sink.go b/sink.go index 35651c0..d28f840 100644 --- a/sink.go +++ b/sink.go @@ -130,9 +130,9 @@ func _Equal[T cmp.Ordered](seq1, seq2 _Seq[T]) bool { // _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) + p1, stop := _Pull(seq1) defer stop() - p2, stop := Pull(seq2) + p2, stop := _Pull(seq2) defer stop() for { diff --git a/transform.go b/transform.go index 34af815..3f526a7 100644 --- a/transform.go +++ b/transform.go @@ -101,9 +101,9 @@ type Zipped[T1, T2 any] struct { // simultaneously. 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 { @@ -128,9 +128,9 @@ func _Merge[T cmp.Ordered](seq1, seq2 _Seq[T]) _Seq[T] { // for determining the order of values. 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() diff --git a/xiter_norangefunc.go b/xiter_norangefunc.go index 1b95571..573ae53 100644 --- a/xiter_norangefunc.go +++ b/xiter_norangefunc.go @@ -14,6 +14,6 @@ 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[T](seq)) +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 index c1872d1..eda0271 100644 --- a/xiter_rangefunc.go +++ b/xiter_rangefunc.go @@ -13,6 +13,6 @@ type _Seq[T any] iter.Seq[T] // Type alias would be nice, but not supported for // _Seq2 represents a two-value iterator. type _Seq2[T1, T2 any] iter.Seq2[T1, T2] -func Pull[T any](seq iter.Seq[T]) (iterator func() (T, bool), stop func()) { - return iter.Pull[T](seq) +func _Pull[T any](seq _Seq[T]) (iterator func() (T, bool), stop func()) { + return iter.Pull[T](iter.Seq[T](seq)) } From 4a379dc947d2835872f5cb15fc16a958b35b8ead Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 13:55:51 -0500 Subject: [PATCH 08/15] internal/gen: implement type name conversion in signatures --- gen_norangefunc.go | 118 +++++++++++++++++------------------ gen_rangefunc.go | 119 ++++++++++++++++++------------------ internal/gen/gen.go | 36 ++++++----- internal/gen/output.go.tmpl | 3 +- 4 files changed, 143 insertions(+), 133 deletions(-) diff --git a/gen_norangefunc.go b/gen_norangefunc.go index c34a275..5322453 100644 --- a/gen_norangefunc.go +++ b/gen_norangefunc.go @@ -10,238 +10,238 @@ import ( "reflect" ) -func Find[T any](seq _Seq[T], f func(T) bool) (r T, ok bool) { +func All[T any](seq Seq[T], f func(T) bool) bool { panic("Not implemented.") } -func Chunks[T any](seq _Seq[T], n int) _Seq[[]T] { +func Any[T any](seq Seq[T], f func(T) bool) bool { panic("Not implemented.") } -func All[T any](seq _Seq[T], f func(T) bool) bool { +func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { panic("Not implemented.") } -func OfMap[K comparable, V any, M ~map[K]V](m M) _Seq2[K, V] { +func AppendTo[T any, S ~[]T](seq Seq[T], s S) S { panic("Not implemented.") } -func Enumerate[T any](seq _Seq[T]) _Seq2[int, T] { +func Bytes(s string) Seq[byte] { panic("Not implemented.") } -func Concat[T any](seqs []_Seq[T]) _Seq[T] { +func Cache[T any](seq Seq[T]) Seq[T] { panic("Not implemented.") } -func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { +func Chunks[T any](seq Seq[T], n int) Seq[[]T] { panic("Not implemented.") } -func CollectSize[T any](seq _Seq[T], len int) []T { +func Collect[T any](seq Seq[T]) []T { panic("Not implemented.") } -func AppendTo[T any, S ~[]T](seq _Seq[T], s S) S { +func CollectSize[T any](seq Seq[T], len int) []T { panic("Not implemented.") } -func OfSlice[T any, S ~[]T](s S) _Seq[T] { +func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { panic("Not implemented.") } -func Reduce[T any, R any](seq _Seq[T], initial R, reducer func(R, T) R) R { +func Concat[T any](seqs []Seq[T]) Seq[T] { panic("Not implemented.") } -func Windows[T any](seq _Seq[T], n int) _Seq[[]T] { +func Contains[T comparable](seq Seq[T], v T) bool { panic("Not implemented.") } -func Skip[T any](seq _Seq[T], n int) _Seq[T] { +func Drain[T any](seq Seq[T]) { panic("Not implemented.") } -func PartitionInto[T any](seq _Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { +func Enumerate[T any](seq Seq[T]) Seq2[int, T] { panic("Not implemented.") } -func SendContext[T any](seq _Seq[T], ctx context.Context, c chan<- T) { +func Equal[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) bool { panic("Not implemented.") } -func Split[T any](seq _Seq[T], f func(T) bool) SplitSeq[T, T] { +func EqualFunc[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2], equal func(T1, T2) bool) bool { panic("Not implemented.") } -func ToPair[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[Pair[T1, T2]] { +func Filter[T any](seq Seq[T], f func(T) bool) Seq[T] { panic("Not implemented.") } -func Merge[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) _Seq[T] { +func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool) { panic("Not implemented.") } -func MergeFunc[T any](seq1 _Seq[T], seq2 _Seq[T], compare func(T, T) int) _Seq[T] { +func Flatten[T any](seq Seq[Seq[T]]) Seq[T] { panic("Not implemented.") } -func Sum[T Addable](seq _Seq[T]) T { +func Fold[T any](seq Seq[T], reducer func(T, T) T) T { panic("Not implemented.") } -func Equal[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) bool { +func FromPair[T1 any, T2 any](seq Seq[Pair[T1, T2]]) Seq2[T1, T2] { panic("Not implemented.") } -func Or[T any](seqs []_Seq[T]) _Seq[T] { +func Generate[T Addable](start T, step T) Seq[T] { panic("Not implemented.") } -func OfChan[T any](c <-chan T) _Seq[T] { +func GoPull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { panic("Not implemented.") } -func Map[T1 any, T2 any](seq _Seq[T1], f func(T1) T2) _Seq[T2] { +func Handle[T any](seq Seq2[T, error], f func(error) bool) Seq[T] { panic("Not implemented.") } -func Contains[T comparable](seq _Seq[T], v T) bool { +func IsSorted[T cmp.Ordered](seq Seq[T]) bool { panic("Not implemented.") } -func Split2[T1 any, T2 any](seq _Seq2[T1, T2]) SplitSeq[T1, T2] { +func IsSortedFunc[T any](seq Seq[T], compare func(T, T) int) bool { panic("Not implemented.") } -func IsSortedFunc[T any](seq _Seq[T], compare func(T, T) int) bool { +func Limit[T any](seq Seq[T], n int) Seq[T] { panic("Not implemented.") } -func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { +func Map[T1 any, T2 any](seq Seq[T1], f func(T1) T2) Seq[T2] { panic("Not implemented.") } -func StringSplit(s string, sep string) _Seq[string] { +func MapKeys[K comparable, V any, M ~map[K]V](m M) Seq[K] { panic("Not implemented.") } -func GoPull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { +func MapValues[K comparable, V any, M ~map[K]V](m M) Seq[V] { panic("Not implemented.") } -func Handle[T any](seq _Seq2[T, error], f func(error) bool) _Seq[T] { +func Max[T cmp.Ordered](seq Seq[T]) T { panic("Not implemented.") } -func MapKeys[K comparable, V any, M ~map[K]V](m M) _Seq[K] { +func Merge[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) Seq[T] { panic("Not implemented.") } -func OfValue(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { +func MergeFunc[T any](seq1 Seq[T], seq2 Seq[T], compare func(T, T) int) Seq[T] { panic("Not implemented.") } -func Any[T any](seq _Seq[T], f func(T) bool) bool { +func Min[T cmp.Ordered](seq Seq[T]) T { panic("Not implemented.") } -func Limit[T any](seq _Seq[T], n int) _Seq[T] { +func Of[T any](vals []T) Seq[T] { panic("Not implemented.") } -func Bytes(s string) _Seq[byte] { +func OfChan[T any](c <-chan T) Seq[T] { panic("Not implemented.") } -func Runes[T ~[]byte | ~string](s T) _Seq[rune] { +func OfMap[K comparable, V any, M ~map[K]V](m M) Seq2[K, V] { panic("Not implemented.") } -func V1[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T1] { +func OfSlice[T any, S ~[]T](s S) Seq[T] { panic("Not implemented.") } -func Drain[T any](seq _Seq[T]) { +func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] { panic("Not implemented.") } -func MapValues[K comparable, V any, M ~map[K]V](m M) _Seq[V] { +func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { panic("Not implemented.") } -func IsSorted[T cmp.Ordered](seq _Seq[T]) bool { +func Or[T any](seqs []Seq[T]) Seq[T] { panic("Not implemented.") } -func Partition[T any](seq _Seq[T], f func(T) bool) (true []T, false []T) { +func Partition[T any](seq Seq[T], f func(T) bool) (true []T, false []T) { panic("Not implemented.") } -func Max[T cmp.Ordered](seq _Seq[T]) T { +func PartitionInto[T any](seq Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { panic("Not implemented.") } -func Fold[T any](seq _Seq[T], reducer func(T, T) T) T { +func Product[T Multiplyable](seq Seq[T]) T { panic("Not implemented.") } -func EqualFunc[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2], equal func(T1, T2) bool) bool { +func Pull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { panic("Not implemented.") } -func Flatten[T any](seq _Seq[_Seq[T]]) _Seq[T] { +func RecvContext[T any](ctx context.Context, c <-chan T) Seq[T] { panic("Not implemented.") } -func FromPair[T1 any, T2 any](seq _Seq[Pair[T1, T2]]) _Seq2[T1, T2] { +func Reduce[T any, R any](seq Seq[T], initial R, reducer func(R, T) R) R { panic("Not implemented.") } -func Filter[T any](seq _Seq[T], f func(T) bool) _Seq[T] { +func Runes[T ~[]byte | ~string](s T) Seq[rune] { panic("Not implemented.") } -func RecvContext[T any](ctx context.Context, c <-chan T) _Seq[T] { +func SendContext[T any](seq Seq[T], ctx context.Context, c chan<- T) { panic("Not implemented.") } -func Generate[T Addable](start T, step T) _Seq[T] { +func Skip[T any](seq Seq[T], n int) Seq[T] { panic("Not implemented.") } -func Min[T cmp.Ordered](seq _Seq[T]) T { +func Split[T any](seq Seq[T], f func(T) bool) SplitSeq[T, T] { panic("Not implemented.") } -func V2[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T2] { +func Split2[T1 any, T2 any](seq Seq2[T1, T2]) SplitSeq[T1, T2] { panic("Not implemented.") } -func Product[T Multiplyable](seq _Seq[T]) T { +func StringSplit(s string, sep string) Seq[string] { panic("Not implemented.") } -func Cache[T any](seq _Seq[T]) _Seq[T] { +func Sum[T Addable](seq Seq[T]) T { panic("Not implemented.") } -func Collect[T any](seq _Seq[T]) []T { +func ToPair[T1 any, T2 any](seq Seq2[T1, T2]) Seq[Pair[T1, T2]] { panic("Not implemented.") } -func Of[T any](vals []T) _Seq[T] { +func V1[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T1] { panic("Not implemented.") } -func Pull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { +func V2[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T2] { panic("Not implemented.") } -func OfSliceIndex[T any, S ~[]T](s S) _Seq2[int, T] { +func Windows[T any](seq Seq[T], n int) Seq[[]T] { panic("Not implemented.") } -func Zip[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2]) _Seq[Zipped[T1, T2]] { +func Zip[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]] { panic("Not implemented.") } diff --git a/gen_rangefunc.go b/gen_rangefunc.go index 8149c1f..2b76662 100644 --- a/gen_rangefunc.go +++ b/gen_rangefunc.go @@ -7,241 +7,242 @@ package xiter import ( "cmp" "context" + "iter" "reflect" ) -func Find[T any](seq _Seq[T], f func(T) bool) (r T, ok bool) { +func All[T any](seq iter.Seq[T], f func(T) bool) bool { panic("Not implemented.") } -func Chunks[T any](seq _Seq[T], n int) _Seq[[]T] { +func Any[T any](seq iter.Seq[T], f func(T) bool) bool { panic("Not implemented.") } -func All[T any](seq _Seq[T], f func(T) bool) bool { +func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { panic("Not implemented.") } -func OfMap[K comparable, V any, M ~map[K]V](m M) _Seq2[K, V] { +func AppendTo[T any, S ~[]T](seq iter.Seq[T], s S) S { panic("Not implemented.") } -func Enumerate[T any](seq _Seq[T]) _Seq2[int, T] { +func Bytes(s string) iter.Seq[byte] { panic("Not implemented.") } -func Concat[T any](seqs []_Seq[T]) _Seq[T] { +func Cache[T any](seq iter.Seq[T]) iter.Seq[T] { panic("Not implemented.") } -func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { +func Chunks[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { panic("Not implemented.") } -func CollectSize[T any](seq _Seq[T], len int) []T { +func Collect[T any](seq iter.Seq[T]) []T { panic("Not implemented.") } -func AppendTo[T any, S ~[]T](seq _Seq[T], s S) S { +func CollectSize[T any](seq iter.Seq[T], len int) []T { panic("Not implemented.") } -func OfSlice[T any, S ~[]T](s S) _Seq[T] { +func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { panic("Not implemented.") } -func Reduce[T any, R any](seq _Seq[T], initial R, reducer func(R, T) R) R { +func Concat[T any](seqs []iter.Seq[T]) iter.Seq[T] { panic("Not implemented.") } -func Windows[T any](seq _Seq[T], n int) _Seq[[]T] { +func Contains[T comparable](seq iter.Seq[T], v T) bool { panic("Not implemented.") } -func Skip[T any](seq _Seq[T], n int) _Seq[T] { +func Drain[T any](seq iter.Seq[T]) { panic("Not implemented.") } -func PartitionInto[T any](seq _Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { +func Enumerate[T any](seq iter.Seq[T]) iter.Seq2[int, T] { panic("Not implemented.") } -func SendContext[T any](seq _Seq[T], ctx context.Context, c chan<- T) { +func Equal[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) bool { panic("Not implemented.") } -func Split[T any](seq _Seq[T], f func(T) bool) SplitSeq[T, T] { +func EqualFunc[T1 any, T2 any](seq1 iter.Seq[T1], seq2 iter.Seq[T2], equal func(T1, T2) bool) bool { panic("Not implemented.") } -func ToPair[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[Pair[T1, T2]] { +func Filter[T any](seq iter.Seq[T], f func(T) bool) iter.Seq[T] { panic("Not implemented.") } -func Merge[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) _Seq[T] { +func Find[T any](seq iter.Seq[T], f func(T) bool) (r T, ok bool) { panic("Not implemented.") } -func MergeFunc[T any](seq1 _Seq[T], seq2 _Seq[T], compare func(T, T) int) _Seq[T] { +func Flatten[T any](seq iter.Seq[iter.Seq[T]]) iter.Seq[T] { panic("Not implemented.") } -func Sum[T Addable](seq _Seq[T]) T { +func Fold[T any](seq iter.Seq[T], reducer func(T, T) T) T { panic("Not implemented.") } -func Equal[T cmp.Ordered](seq1 _Seq[T], seq2 _Seq[T]) bool { +func FromPair[T1 any, T2 any](seq iter.Seq[Pair[T1, T2]]) iter.Seq2[T1, T2] { panic("Not implemented.") } -func Or[T any](seqs []_Seq[T]) _Seq[T] { +func Generate[T Addable](start T, step T) iter.Seq[T] { panic("Not implemented.") } -func OfChan[T any](c <-chan T) _Seq[T] { +func GoPull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { panic("Not implemented.") } -func Map[T1 any, T2 any](seq _Seq[T1], f func(T1) T2) _Seq[T2] { +func Handle[T any](seq iter.Seq2[T, error], f func(error) bool) iter.Seq[T] { panic("Not implemented.") } -func Contains[T comparable](seq _Seq[T], v T) bool { +func IsSorted[T cmp.Ordered](seq iter.Seq[T]) bool { panic("Not implemented.") } -func Split2[T1 any, T2 any](seq _Seq2[T1, T2]) SplitSeq[T1, T2] { +func IsSortedFunc[T any](seq iter.Seq[T], compare func(T, T) int) bool { panic("Not implemented.") } -func IsSortedFunc[T any](seq _Seq[T], compare func(T, T) int) bool { +func Limit[T any](seq iter.Seq[T], n int) iter.Seq[T] { panic("Not implemented.") } -func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { +func Map[T1 any, T2 any](seq iter.Seq[T1], f func(T1) T2) iter.Seq[T2] { panic("Not implemented.") } -func StringSplit(s string, sep string) _Seq[string] { +func MapKeys[K comparable, V any, M ~map[K]V](m M) iter.Seq[K] { panic("Not implemented.") } -func GoPull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { +func MapValues[K comparable, V any, M ~map[K]V](m M) iter.Seq[V] { panic("Not implemented.") } -func Handle[T any](seq _Seq2[T, error], f func(error) bool) _Seq[T] { +func Max[T cmp.Ordered](seq iter.Seq[T]) T { panic("Not implemented.") } -func MapKeys[K comparable, V any, M ~map[K]V](m M) _Seq[K] { +func Merge[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) iter.Seq[T] { panic("Not implemented.") } -func OfValue(v reflect.Value) _Seq2[reflect.Value, reflect.Value] { +func MergeFunc[T any](seq1 iter.Seq[T], seq2 iter.Seq[T], compare func(T, T) int) iter.Seq[T] { panic("Not implemented.") } -func Any[T any](seq _Seq[T], f func(T) bool) bool { +func Min[T cmp.Ordered](seq iter.Seq[T]) T { panic("Not implemented.") } -func Limit[T any](seq _Seq[T], n int) _Seq[T] { +func Of[T any](vals []T) iter.Seq[T] { panic("Not implemented.") } -func Bytes(s string) _Seq[byte] { +func OfChan[T any](c <-chan T) iter.Seq[T] { panic("Not implemented.") } -func Runes[T ~[]byte | ~string](s T) _Seq[rune] { +func OfMap[K comparable, V any, M ~map[K]V](m M) iter.Seq2[K, V] { panic("Not implemented.") } -func V1[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T1] { +func OfSlice[T any, S ~[]T](s S) iter.Seq[T] { panic("Not implemented.") } -func Drain[T any](seq _Seq[T]) { +func OfSliceIndex[T any, S ~[]T](s S) iter.Seq2[int, T] { panic("Not implemented.") } -func MapValues[K comparable, V any, M ~map[K]V](m M) _Seq[V] { +func OfValue(v reflect.Value) iter.Seq2[reflect.Value, reflect.Value] { panic("Not implemented.") } -func IsSorted[T cmp.Ordered](seq _Seq[T]) bool { +func Or[T any](seqs []iter.Seq[T]) iter.Seq[T] { panic("Not implemented.") } -func Partition[T any](seq _Seq[T], f func(T) bool) (true []T, false []T) { +func Partition[T any](seq iter.Seq[T], f func(T) bool) (true []T, false []T) { panic("Not implemented.") } -func Max[T cmp.Ordered](seq _Seq[T]) T { +func PartitionInto[T any](seq iter.Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { panic("Not implemented.") } -func Fold[T any](seq _Seq[T], reducer func(T, T) T) T { +func Product[T Multiplyable](seq iter.Seq[T]) T { panic("Not implemented.") } -func EqualFunc[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2], equal func(T1, T2) bool) bool { +func Pull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { panic("Not implemented.") } -func Flatten[T any](seq _Seq[_Seq[T]]) _Seq[T] { +func RecvContext[T any](ctx context.Context, c <-chan T) iter.Seq[T] { panic("Not implemented.") } -func FromPair[T1 any, T2 any](seq _Seq[Pair[T1, T2]]) _Seq2[T1, T2] { +func Reduce[T any, R any](seq iter.Seq[T], initial R, reducer func(R, T) R) R { panic("Not implemented.") } -func Filter[T any](seq _Seq[T], f func(T) bool) _Seq[T] { +func Runes[T ~[]byte | ~string](s T) iter.Seq[rune] { panic("Not implemented.") } -func RecvContext[T any](ctx context.Context, c <-chan T) _Seq[T] { +func SendContext[T any](seq iter.Seq[T], ctx context.Context, c chan<- T) { panic("Not implemented.") } -func Generate[T Addable](start T, step T) _Seq[T] { +func Skip[T any](seq iter.Seq[T], n int) iter.Seq[T] { panic("Not implemented.") } -func Min[T cmp.Ordered](seq _Seq[T]) T { +func Split[T any](seq iter.Seq[T], f func(T) bool) SplitSeq[T, T] { panic("Not implemented.") } -func V2[T1 any, T2 any](seq _Seq2[T1, T2]) _Seq[T2] { +func Split2[T1 any, T2 any](seq iter.Seq2[T1, T2]) SplitSeq[T1, T2] { panic("Not implemented.") } -func Product[T Multiplyable](seq _Seq[T]) T { +func StringSplit(s string, sep string) iter.Seq[string] { panic("Not implemented.") } -func Cache[T any](seq _Seq[T]) _Seq[T] { +func Sum[T Addable](seq iter.Seq[T]) T { panic("Not implemented.") } -func Collect[T any](seq _Seq[T]) []T { +func ToPair[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[Pair[T1, T2]] { panic("Not implemented.") } -func Of[T any](vals []T) _Seq[T] { +func V1[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T1] { panic("Not implemented.") } -func Pull[T any](seq _Seq[T]) (iter func() (T, bool), stop func()) { +func V2[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T2] { panic("Not implemented.") } -func OfSliceIndex[T any, S ~[]T](s S) _Seq2[int, T] { +func Windows[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { panic("Not implemented.") } -func Zip[T1 any, T2 any](seq1 _Seq[T1], seq2 _Seq[T2]) _Seq[Zipped[T1, T2]] { +func Zip[T1 any, T2 any](seq1 iter.Seq[T1], seq2 iter.Seq[T2]) iter.Seq[Zipped[T1, T2]] { panic("Not implemented.") } diff --git a/internal/gen/gen.go b/internal/gen/gen.go index 7933925..4cdb7e6 100644 --- a/internal/gen/gen.go +++ b/internal/gen/gen.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "cmp" _ "embed" "fmt" "go/format" @@ -9,6 +10,7 @@ import ( "log/slog" "os" "regexp" + "slices" "strings" "text/template" @@ -22,14 +24,14 @@ var ( outputTemplate string tmpl = template.Must(template.New("output").Funcs(funcMap).Parse(outputTemplate)) funcMap = map[string]any{ - "convertName": convertName, - "typeParamSlice": listToSlice[*types.TypeParam], - "tupleSlice": listToSlice[*types.Var], - "convertType": convertType, + "convertFuncName": convertFuncName, + "typeParamSlice": listToSlice[*types.TypeParam], + "tupleSlice": listToSlice[*types.Var], + "convertType": convertType, } ) -func convertName(name string) string { +func convertFuncName(name string) string { return strings.TrimPrefix(name, "_") } @@ -55,15 +57,17 @@ func convertType(rangefunc bool, t types.Type) string { pkg = t.Obj().Pkg().Name() + "." } + name := convertTypeName(rangefunc, t.Obj().Name()) + if t.TypeArgs().Len() == 0 { - return pkg + t.Obj().Name() + return pkg + name } typeArgs := make([]string, 0, t.TypeArgs().Len()) for _, arg := range listToSlice(t.TypeArgs()) { typeArgs = append(typeArgs, convertType(rangefunc, arg)) } - return fmt.Sprintf("%v%v[%v]", pkg, t.Obj().Name(), strings.Join(typeArgs, ",")) + return fmt.Sprintf("%v%v[%v]", pkg, name, strings.Join(typeArgs, ",")) case *types.Slice: return fmt.Sprintf("[]%v", convertType(rangefunc, t.Elem())) @@ -76,14 +80,17 @@ func convertType(rangefunc bool, t types.Type) string { } } -func join[T any](sep string, s []T) string { - var i string - var buf strings.Builder - for _, v := range s { - fmt.Fprintf(&buf, "%v%v", i, v) - i = sep +func convertTypeName(rangefunc bool, name string) string { + cut, ok := strings.CutPrefix(name, "_") + if !ok { + return name + } + + if !rangefunc { + return cut } - return buf.String() + + return "iter." + cut } func load() []*types.Func { @@ -106,6 +113,7 @@ func load() []*types.Func { funcs = append(funcs, f) } + slices.SortFunc(funcs, func(f1, f2 *types.Func) int { return cmp.Compare(f1.Name(), f2.Name()) }) return funcs } diff --git a/internal/gen/output.go.tmpl b/internal/gen/output.go.tmpl index 24f2e81..2e04de7 100644 --- a/internal/gen/output.go.tmpl +++ b/internal/gen/output.go.tmpl @@ -8,10 +8,11 @@ import ( "cmp" "context" "reflect" + {{if .RangeFunc}}"iter"{{end}} ) {{range .Funcs}} - func {{.Name | convertName}}{{with .Type.TypeParams | typeParamSlice}}[ + func {{.Name | convertFuncName}}{{with .Type.TypeParams | typeParamSlice}}[ {{- range .}} {{- .}} {{.Constraint | convertType $.RangeFunc}}, {{- end -}} From a1f01d0ec1972d7b145dd298fb520549402e8e85 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 14:00:46 -0500 Subject: [PATCH 09/15] internal/gen: call underlying function without conversions --- gen_norangefunc.go | 118 ++++++++++++++++++------------------ gen_rangefunc.go | 118 ++++++++++++++++++------------------ internal/gen/output.go.tmpl | 6 +- 3 files changed, 123 insertions(+), 119 deletions(-) diff --git a/gen_norangefunc.go b/gen_norangefunc.go index 5322453..234eb1e 100644 --- a/gen_norangefunc.go +++ b/gen_norangefunc.go @@ -11,237 +11,237 @@ import ( ) func All[T any](seq Seq[T], f func(T) bool) bool { - panic("Not implemented.") + return _All(seq, f) } func Any[T any](seq Seq[T], f func(T) bool) bool { - panic("Not implemented.") + return _Any(seq, f) } func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { - panic("Not implemented.") + return _AppendSplitTo(seq, s1, s2) } func AppendTo[T any, S ~[]T](seq Seq[T], s S) S { - panic("Not implemented.") + return _AppendTo(seq, s) } func Bytes(s string) Seq[byte] { - panic("Not implemented.") + return _Bytes(s) } func Cache[T any](seq Seq[T]) Seq[T] { - panic("Not implemented.") + return _Cache(seq) } func Chunks[T any](seq Seq[T], n int) Seq[[]T] { - panic("Not implemented.") + return _Chunks(seq, n) } func Collect[T any](seq Seq[T]) []T { - panic("Not implemented.") + return _Collect(seq) } func CollectSize[T any](seq Seq[T], len int) []T { - panic("Not implemented.") + return _CollectSize(seq, len) } func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { - panic("Not implemented.") + return _CollectSplit(seq) } func Concat[T any](seqs []Seq[T]) Seq[T] { - panic("Not implemented.") + return _Concat(seqs) } func Contains[T comparable](seq Seq[T], v T) bool { - panic("Not implemented.") + return _Contains(seq, v) } func Drain[T any](seq Seq[T]) { - panic("Not implemented.") + return _Drain(seq) } func Enumerate[T any](seq Seq[T]) Seq2[int, T] { - panic("Not implemented.") + return _Enumerate(seq) } func Equal[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) bool { - panic("Not implemented.") + return _Equal(seq1, seq2) } func EqualFunc[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2], equal func(T1, T2) bool) bool { - panic("Not implemented.") + return _EqualFunc(seq1, seq2, equal) } func Filter[T any](seq Seq[T], f func(T) bool) Seq[T] { - panic("Not implemented.") + return _Filter(seq, f) } func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool) { - panic("Not implemented.") + return _Find(seq, f) } func Flatten[T any](seq Seq[Seq[T]]) Seq[T] { - panic("Not implemented.") + return _Flatten(seq) } func Fold[T any](seq Seq[T], reducer func(T, T) T) T { - panic("Not implemented.") + return _Fold(seq, reducer) } func FromPair[T1 any, T2 any](seq Seq[Pair[T1, T2]]) Seq2[T1, T2] { - panic("Not implemented.") + return _FromPair(seq) } func Generate[T Addable](start T, step T) Seq[T] { - panic("Not implemented.") + return _Generate(start, step) } func GoPull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { - panic("Not implemented.") + return _GoPull(seq) } func Handle[T any](seq Seq2[T, error], f func(error) bool) Seq[T] { - panic("Not implemented.") + return _Handle(seq, f) } func IsSorted[T cmp.Ordered](seq Seq[T]) bool { - panic("Not implemented.") + return _IsSorted(seq) } func IsSortedFunc[T any](seq Seq[T], compare func(T, T) int) bool { - panic("Not implemented.") + return _IsSortedFunc(seq, compare) } func Limit[T any](seq Seq[T], n int) Seq[T] { - panic("Not implemented.") + return _Limit(seq, n) } func Map[T1 any, T2 any](seq Seq[T1], f func(T1) T2) Seq[T2] { - panic("Not implemented.") + return _Map(seq, f) } func MapKeys[K comparable, V any, M ~map[K]V](m M) Seq[K] { - panic("Not implemented.") + return _MapKeys(m) } func MapValues[K comparable, V any, M ~map[K]V](m M) Seq[V] { - panic("Not implemented.") + return _MapValues(m) } func Max[T cmp.Ordered](seq Seq[T]) T { - panic("Not implemented.") + return _Max(seq) } func Merge[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) Seq[T] { - panic("Not implemented.") + return _Merge(seq1, seq2) } func MergeFunc[T any](seq1 Seq[T], seq2 Seq[T], compare func(T, T) int) Seq[T] { - panic("Not implemented.") + return _MergeFunc(seq1, seq2, compare) } func Min[T cmp.Ordered](seq Seq[T]) T { - panic("Not implemented.") + return _Min(seq) } func Of[T any](vals []T) Seq[T] { - panic("Not implemented.") + return _Of(vals) } func OfChan[T any](c <-chan T) Seq[T] { - panic("Not implemented.") + return _OfChan(c) } func OfMap[K comparable, V any, M ~map[K]V](m M) Seq2[K, V] { - panic("Not implemented.") + return _OfMap(m) } func OfSlice[T any, S ~[]T](s S) Seq[T] { - panic("Not implemented.") + return _OfSlice(s) } func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] { - panic("Not implemented.") + return _OfSliceIndex(s) } func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { - panic("Not implemented.") + return _OfValue(v) } func Or[T any](seqs []Seq[T]) Seq[T] { - panic("Not implemented.") + return _Or(seqs) } func Partition[T any](seq Seq[T], f func(T) bool) (true []T, false []T) { - panic("Not implemented.") + return _Partition(seq, f) } func PartitionInto[T any](seq Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { - panic("Not implemented.") + return _PartitionInto(seq, f, true, false) } func Product[T Multiplyable](seq Seq[T]) T { - panic("Not implemented.") + return _Product(seq) } func Pull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { - panic("Not implemented.") + return _Pull(seq) } func RecvContext[T any](ctx context.Context, c <-chan T) Seq[T] { - panic("Not implemented.") + return _RecvContext(ctx, c) } func Reduce[T any, R any](seq Seq[T], initial R, reducer func(R, T) R) R { - panic("Not implemented.") + return _Reduce(seq, initial, reducer) } func Runes[T ~[]byte | ~string](s T) Seq[rune] { - panic("Not implemented.") + return _Runes(s) } func SendContext[T any](seq Seq[T], ctx context.Context, c chan<- T) { - panic("Not implemented.") + return _SendContext(seq, ctx, c) } func Skip[T any](seq Seq[T], n int) Seq[T] { - panic("Not implemented.") + return _Skip(seq, n) } func Split[T any](seq Seq[T], f func(T) bool) SplitSeq[T, T] { - panic("Not implemented.") + return _Split(seq, f) } func Split2[T1 any, T2 any](seq Seq2[T1, T2]) SplitSeq[T1, T2] { - panic("Not implemented.") + return _Split2(seq) } func StringSplit(s string, sep string) Seq[string] { - panic("Not implemented.") + return _StringSplit(s, sep) } func Sum[T Addable](seq Seq[T]) T { - panic("Not implemented.") + return _Sum(seq) } func ToPair[T1 any, T2 any](seq Seq2[T1, T2]) Seq[Pair[T1, T2]] { - panic("Not implemented.") + return _ToPair(seq) } func V1[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T1] { - panic("Not implemented.") + return _V1(seq) } func V2[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T2] { - panic("Not implemented.") + return _V2(seq) } func Windows[T any](seq Seq[T], n int) Seq[[]T] { - panic("Not implemented.") + return _Windows(seq, n) } func Zip[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]] { - panic("Not implemented.") + return _Zip(seq1, seq2) } diff --git a/gen_rangefunc.go b/gen_rangefunc.go index 2b76662..0bc4319 100644 --- a/gen_rangefunc.go +++ b/gen_rangefunc.go @@ -12,237 +12,237 @@ import ( ) func All[T any](seq iter.Seq[T], f func(T) bool) bool { - panic("Not implemented.") + return _All(seq, f) } func Any[T any](seq iter.Seq[T], f func(T) bool) bool { - panic("Not implemented.") + return _Any(seq, f) } func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { - panic("Not implemented.") + return _AppendSplitTo(seq, s1, s2) } func AppendTo[T any, S ~[]T](seq iter.Seq[T], s S) S { - panic("Not implemented.") + return _AppendTo(seq, s) } func Bytes(s string) iter.Seq[byte] { - panic("Not implemented.") + return _Bytes(s) } func Cache[T any](seq iter.Seq[T]) iter.Seq[T] { - panic("Not implemented.") + return _Cache(seq) } func Chunks[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { - panic("Not implemented.") + return _Chunks(seq, n) } func Collect[T any](seq iter.Seq[T]) []T { - panic("Not implemented.") + return _Collect(seq) } func CollectSize[T any](seq iter.Seq[T], len int) []T { - panic("Not implemented.") + return _CollectSize(seq, len) } func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { - panic("Not implemented.") + return _CollectSplit(seq) } func Concat[T any](seqs []iter.Seq[T]) iter.Seq[T] { - panic("Not implemented.") + return _Concat(seqs) } func Contains[T comparable](seq iter.Seq[T], v T) bool { - panic("Not implemented.") + return _Contains(seq, v) } func Drain[T any](seq iter.Seq[T]) { - panic("Not implemented.") + return _Drain(seq) } func Enumerate[T any](seq iter.Seq[T]) iter.Seq2[int, T] { - panic("Not implemented.") + return _Enumerate(seq) } func Equal[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) bool { - panic("Not implemented.") + return _Equal(seq1, seq2) } func EqualFunc[T1 any, T2 any](seq1 iter.Seq[T1], seq2 iter.Seq[T2], equal func(T1, T2) bool) bool { - panic("Not implemented.") + return _EqualFunc(seq1, seq2, equal) } func Filter[T any](seq iter.Seq[T], f func(T) bool) iter.Seq[T] { - panic("Not implemented.") + return _Filter(seq, f) } func Find[T any](seq iter.Seq[T], f func(T) bool) (r T, ok bool) { - panic("Not implemented.") + return _Find(seq, f) } func Flatten[T any](seq iter.Seq[iter.Seq[T]]) iter.Seq[T] { - panic("Not implemented.") + return _Flatten(seq) } func Fold[T any](seq iter.Seq[T], reducer func(T, T) T) T { - panic("Not implemented.") + return _Fold(seq, reducer) } func FromPair[T1 any, T2 any](seq iter.Seq[Pair[T1, T2]]) iter.Seq2[T1, T2] { - panic("Not implemented.") + return _FromPair(seq) } func Generate[T Addable](start T, step T) iter.Seq[T] { - panic("Not implemented.") + return _Generate(start, step) } func GoPull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { - panic("Not implemented.") + return _GoPull(seq) } func Handle[T any](seq iter.Seq2[T, error], f func(error) bool) iter.Seq[T] { - panic("Not implemented.") + return _Handle(seq, f) } func IsSorted[T cmp.Ordered](seq iter.Seq[T]) bool { - panic("Not implemented.") + return _IsSorted(seq) } func IsSortedFunc[T any](seq iter.Seq[T], compare func(T, T) int) bool { - panic("Not implemented.") + return _IsSortedFunc(seq, compare) } func Limit[T any](seq iter.Seq[T], n int) iter.Seq[T] { - panic("Not implemented.") + return _Limit(seq, n) } func Map[T1 any, T2 any](seq iter.Seq[T1], f func(T1) T2) iter.Seq[T2] { - panic("Not implemented.") + return _Map(seq, f) } func MapKeys[K comparable, V any, M ~map[K]V](m M) iter.Seq[K] { - panic("Not implemented.") + return _MapKeys(m) } func MapValues[K comparable, V any, M ~map[K]V](m M) iter.Seq[V] { - panic("Not implemented.") + return _MapValues(m) } func Max[T cmp.Ordered](seq iter.Seq[T]) T { - panic("Not implemented.") + return _Max(seq) } func Merge[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) iter.Seq[T] { - panic("Not implemented.") + return _Merge(seq1, seq2) } func MergeFunc[T any](seq1 iter.Seq[T], seq2 iter.Seq[T], compare func(T, T) int) iter.Seq[T] { - panic("Not implemented.") + return _MergeFunc(seq1, seq2, compare) } func Min[T cmp.Ordered](seq iter.Seq[T]) T { - panic("Not implemented.") + return _Min(seq) } func Of[T any](vals []T) iter.Seq[T] { - panic("Not implemented.") + return _Of(vals) } func OfChan[T any](c <-chan T) iter.Seq[T] { - panic("Not implemented.") + return _OfChan(c) } func OfMap[K comparable, V any, M ~map[K]V](m M) iter.Seq2[K, V] { - panic("Not implemented.") + return _OfMap(m) } func OfSlice[T any, S ~[]T](s S) iter.Seq[T] { - panic("Not implemented.") + return _OfSlice(s) } func OfSliceIndex[T any, S ~[]T](s S) iter.Seq2[int, T] { - panic("Not implemented.") + return _OfSliceIndex(s) } func OfValue(v reflect.Value) iter.Seq2[reflect.Value, reflect.Value] { - panic("Not implemented.") + return _OfValue(v) } func Or[T any](seqs []iter.Seq[T]) iter.Seq[T] { - panic("Not implemented.") + return _Or(seqs) } func Partition[T any](seq iter.Seq[T], f func(T) bool) (true []T, false []T) { - panic("Not implemented.") + return _Partition(seq, f) } func PartitionInto[T any](seq iter.Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { - panic("Not implemented.") + return _PartitionInto(seq, f, true, false) } func Product[T Multiplyable](seq iter.Seq[T]) T { - panic("Not implemented.") + return _Product(seq) } func Pull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { - panic("Not implemented.") + return _Pull(seq) } func RecvContext[T any](ctx context.Context, c <-chan T) iter.Seq[T] { - panic("Not implemented.") + return _RecvContext(ctx, c) } func Reduce[T any, R any](seq iter.Seq[T], initial R, reducer func(R, T) R) R { - panic("Not implemented.") + return _Reduce(seq, initial, reducer) } func Runes[T ~[]byte | ~string](s T) iter.Seq[rune] { - panic("Not implemented.") + return _Runes(s) } func SendContext[T any](seq iter.Seq[T], ctx context.Context, c chan<- T) { - panic("Not implemented.") + return _SendContext(seq, ctx, c) } func Skip[T any](seq iter.Seq[T], n int) iter.Seq[T] { - panic("Not implemented.") + return _Skip(seq, n) } func Split[T any](seq iter.Seq[T], f func(T) bool) SplitSeq[T, T] { - panic("Not implemented.") + return _Split(seq, f) } func Split2[T1 any, T2 any](seq iter.Seq2[T1, T2]) SplitSeq[T1, T2] { - panic("Not implemented.") + return _Split2(seq) } func StringSplit(s string, sep string) iter.Seq[string] { - panic("Not implemented.") + return _StringSplit(s, sep) } func Sum[T Addable](seq iter.Seq[T]) T { - panic("Not implemented.") + return _Sum(seq) } func ToPair[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[Pair[T1, T2]] { - panic("Not implemented.") + return _ToPair(seq) } func V1[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T1] { - panic("Not implemented.") + return _V1(seq) } func V2[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T2] { - panic("Not implemented.") + return _V2(seq) } func Windows[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { - panic("Not implemented.") + return _Windows(seq, n) } func Zip[T1 any, T2 any](seq1 iter.Seq[T1], seq2 iter.Seq[T2]) iter.Seq[Zipped[T1, T2]] { - panic("Not implemented.") + return _Zip(seq1, seq2) } diff --git a/internal/gen/output.go.tmpl b/internal/gen/output.go.tmpl index 2e04de7..ec80e1e 100644 --- a/internal/gen/output.go.tmpl +++ b/internal/gen/output.go.tmpl @@ -25,6 +25,10 @@ import ( {{- .Name}} {{.Type | convertType $.RangeFunc}}, {{- end -}} ) { - panic("Not implemented.") + return {{.Name}}( + {{- range .Type.Params | tupleSlice}} + {{- .Name }}, + {{- end -}} + ) } {{end}} From 1c0853b3d4fb00f0110fa9754d27cffe896a321f Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 14:57:46 -0500 Subject: [PATCH 10/15] internal/gen: convert arguments and returns that don't involve element types --- gen_norangefunc.go | 177 ++++++++++++++++++++++++------------ gen_rangefunc.go | 177 ++++++++++++++++++++++++------------ internal/gen/gen.go | 61 ++++++++++++- internal/gen/output.go.tmpl | 7 +- 4 files changed, 300 insertions(+), 122 deletions(-) diff --git a/gen_norangefunc.go b/gen_norangefunc.go index 234eb1e..224e627 100644 --- a/gen_norangefunc.go +++ b/gen_norangefunc.go @@ -11,237 +11,296 @@ import ( ) func All[T any](seq Seq[T], f func(T) bool) bool { - return _All(seq, f) + _r0 := _All(_Seq[T](seq), f) + return _r0 } func Any[T any](seq Seq[T], f func(T) bool) bool { - return _Any(seq, f) + _r0 := _Any(_Seq[T](seq), f) + return _r0 } func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { - return _AppendSplitTo(seq, s1, s2) + _r0, _r1 := _AppendSplitTo(seq, s1, s2) + return _r0, _r1 } func AppendTo[T any, S ~[]T](seq Seq[T], s S) S { - return _AppendTo(seq, s) + _r0 := _AppendTo(_Seq[T](seq), s) + return _r0 } func Bytes(s string) Seq[byte] { - return _Bytes(s) + _r0 := _Bytes(s) + return Seq[byte](_r0) } func Cache[T any](seq Seq[T]) Seq[T] { - return _Cache(seq) + _r0 := _Cache(_Seq[T](seq)) + return Seq[T](_r0) } func Chunks[T any](seq Seq[T], n int) Seq[[]T] { - return _Chunks(seq, n) + _r0 := _Chunks(_Seq[T](seq), n) + return Seq[[]T](_r0) } func Collect[T any](seq Seq[T]) []T { - return _Collect(seq) + _r0 := _Collect(_Seq[T](seq)) + return _r0 } func CollectSize[T any](seq Seq[T], len int) []T { - return _CollectSize(seq, len) + _r0 := _CollectSize(_Seq[T](seq), len) + return _r0 } func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { - return _CollectSplit(seq) + _r0, _r1 := _CollectSplit(seq) + return _r0, _r1 } func Concat[T any](seqs []Seq[T]) Seq[T] { - return _Concat(seqs) + _r0 := _Concat(seqs) + return Seq[T](_r0) } func Contains[T comparable](seq Seq[T], v T) bool { - return _Contains(seq, v) + _r0 := _Contains(_Seq[T](seq), v) + return _r0 } func Drain[T any](seq Seq[T]) { - return _Drain(seq) + _Drain(_Seq[T](seq)) + } func Enumerate[T any](seq Seq[T]) Seq2[int, T] { - return _Enumerate(seq) + _r0 := _Enumerate(_Seq[T](seq)) + return Seq2[int, T](_r0) } func Equal[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) bool { - return _Equal(seq1, seq2) + _r0 := _Equal(_Seq[T](seq1), _Seq[T](seq2)) + return _r0 } func EqualFunc[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2], equal func(T1, T2) bool) bool { - return _EqualFunc(seq1, seq2, equal) + _r0 := _EqualFunc(_Seq[T1](seq1), _Seq[T2](seq2), equal) + return _r0 } func Filter[T any](seq Seq[T], f func(T) bool) Seq[T] { - return _Filter(seq, f) + _r0 := _Filter(_Seq[T](seq), f) + return Seq[T](_r0) } func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool) { - return _Find(seq, f) + _r0, _r1 := _Find(_Seq[T](seq), f) + return _r0, _r1 } func Flatten[T any](seq Seq[Seq[T]]) Seq[T] { - return _Flatten(seq) + _r0 := _Flatten(_Seq[Seq[T]](seq)) + return Seq[T](_r0) } func Fold[T any](seq Seq[T], reducer func(T, T) T) T { - return _Fold(seq, reducer) + _r0 := _Fold(_Seq[T](seq), reducer) + return _r0 } func FromPair[T1 any, T2 any](seq Seq[Pair[T1, T2]]) Seq2[T1, T2] { - return _FromPair(seq) + _r0 := _FromPair(_Seq[Pair[T1, T2]](seq)) + return Seq2[T1, T2](_r0) } func Generate[T Addable](start T, step T) Seq[T] { - return _Generate(start, step) + _r0 := _Generate(start, step) + return Seq[T](_r0) } func GoPull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { - return _GoPull(seq) + _r0, _r1 := _GoPull(_Seq[T](seq)) + return _r0, _r1 } func Handle[T any](seq Seq2[T, error], f func(error) bool) Seq[T] { - return _Handle(seq, f) + _r0 := _Handle(_Seq2[T, error](seq), f) + return Seq[T](_r0) } func IsSorted[T cmp.Ordered](seq Seq[T]) bool { - return _IsSorted(seq) + _r0 := _IsSorted(_Seq[T](seq)) + return _r0 } func IsSortedFunc[T any](seq Seq[T], compare func(T, T) int) bool { - return _IsSortedFunc(seq, compare) + _r0 := _IsSortedFunc(_Seq[T](seq), compare) + return _r0 } func Limit[T any](seq Seq[T], n int) Seq[T] { - return _Limit(seq, n) + _r0 := _Limit(_Seq[T](seq), n) + return Seq[T](_r0) } func Map[T1 any, T2 any](seq Seq[T1], f func(T1) T2) Seq[T2] { - return _Map(seq, f) + _r0 := _Map(_Seq[T1](seq), f) + return Seq[T2](_r0) } func MapKeys[K comparable, V any, M ~map[K]V](m M) Seq[K] { - return _MapKeys(m) + _r0 := _MapKeys(m) + return Seq[K](_r0) } func MapValues[K comparable, V any, M ~map[K]V](m M) Seq[V] { - return _MapValues(m) + _r0 := _MapValues(m) + return Seq[V](_r0) } func Max[T cmp.Ordered](seq Seq[T]) T { - return _Max(seq) + _r0 := _Max(_Seq[T](seq)) + return _r0 } func Merge[T cmp.Ordered](seq1 Seq[T], seq2 Seq[T]) Seq[T] { - return _Merge(seq1, seq2) + _r0 := _Merge(_Seq[T](seq1), _Seq[T](seq2)) + return Seq[T](_r0) } func MergeFunc[T any](seq1 Seq[T], seq2 Seq[T], compare func(T, T) int) Seq[T] { - return _MergeFunc(seq1, seq2, compare) + _r0 := _MergeFunc(_Seq[T](seq1), _Seq[T](seq2), compare) + return Seq[T](_r0) } func Min[T cmp.Ordered](seq Seq[T]) T { - return _Min(seq) + _r0 := _Min(_Seq[T](seq)) + return _r0 } func Of[T any](vals []T) Seq[T] { - return _Of(vals) + _r0 := _Of(vals) + return Seq[T](_r0) } func OfChan[T any](c <-chan T) Seq[T] { - return _OfChan(c) + _r0 := _OfChan(c) + return Seq[T](_r0) } func OfMap[K comparable, V any, M ~map[K]V](m M) Seq2[K, V] { - return _OfMap(m) + _r0 := _OfMap(m) + return Seq2[K, V](_r0) } func OfSlice[T any, S ~[]T](s S) Seq[T] { - return _OfSlice(s) + _r0 := _OfSlice(s) + return Seq[T](_r0) } func OfSliceIndex[T any, S ~[]T](s S) Seq2[int, T] { - return _OfSliceIndex(s) + _r0 := _OfSliceIndex(s) + return Seq2[int, T](_r0) } func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { - return _OfValue(v) + _r0 := _OfValue(v) + return Seq2[reflect.Value, reflect.Value](_r0) } func Or[T any](seqs []Seq[T]) Seq[T] { - return _Or(seqs) + _r0 := _Or(seqs) + return Seq[T](_r0) } func Partition[T any](seq Seq[T], f func(T) bool) (true []T, false []T) { - return _Partition(seq, f) + _r0, _r1 := _Partition(_Seq[T](seq), f) + return _r0, _r1 } func PartitionInto[T any](seq Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { - return _PartitionInto(seq, f, true, false) + _r0, _r1 := _PartitionInto(_Seq[T](seq), f, true, false) + return _r0, _r1 } func Product[T Multiplyable](seq Seq[T]) T { - return _Product(seq) + _r0 := _Product(_Seq[T](seq)) + return _r0 } func Pull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { - return _Pull(seq) + _r0, _r1 := _Pull(_Seq[T](seq)) + return _r0, _r1 } func RecvContext[T any](ctx context.Context, c <-chan T) Seq[T] { - return _RecvContext(ctx, c) + _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 { - return _Reduce(seq, initial, reducer) + _r0 := _Reduce(_Seq[T](seq), initial, reducer) + return _r0 } func Runes[T ~[]byte | ~string](s T) Seq[rune] { - return _Runes(s) + _r0 := _Runes(s) + return Seq[rune](_r0) } func SendContext[T any](seq Seq[T], ctx context.Context, c chan<- T) { - return _SendContext(seq, ctx, c) + _SendContext(_Seq[T](seq), ctx, c) + } func Skip[T any](seq Seq[T], n int) Seq[T] { - return _Skip(seq, n) + _r0 := _Skip(_Seq[T](seq), n) + return Seq[T](_r0) } func Split[T any](seq Seq[T], f func(T) bool) SplitSeq[T, T] { - return _Split(seq, f) + _r0 := _Split(_Seq[T](seq), f) + return _r0 } func Split2[T1 any, T2 any](seq Seq2[T1, T2]) SplitSeq[T1, T2] { - return _Split2(seq) + _r0 := _Split2(_Seq2[T1, T2](seq)) + return _r0 } func StringSplit(s string, sep string) Seq[string] { - return _StringSplit(s, sep) + _r0 := _StringSplit(s, sep) + return Seq[string](_r0) } func Sum[T Addable](seq Seq[T]) T { - return _Sum(seq) + _r0 := _Sum(_Seq[T](seq)) + return _r0 } func ToPair[T1 any, T2 any](seq Seq2[T1, T2]) Seq[Pair[T1, T2]] { - return _ToPair(seq) + _r0 := _ToPair(_Seq2[T1, T2](seq)) + return Seq[Pair[T1, T2]](_r0) } func V1[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T1] { - return _V1(seq) + _r0 := _V1(_Seq2[T1, T2](seq)) + return Seq[T1](_r0) } func V2[T1 any, T2 any](seq Seq2[T1, T2]) Seq[T2] { - return _V2(seq) + _r0 := _V2(_Seq2[T1, T2](seq)) + return Seq[T2](_r0) } func Windows[T any](seq Seq[T], n int) Seq[[]T] { - return _Windows(seq, n) + _r0 := _Windows(_Seq[T](seq), n) + return Seq[[]T](_r0) } func Zip[T1 any, T2 any](seq1 Seq[T1], seq2 Seq[T2]) Seq[Zipped[T1, T2]] { - return _Zip(seq1, seq2) + _r0 := _Zip(_Seq[T1](seq1), _Seq[T2](seq2)) + return Seq[Zipped[T1, T2]](_r0) } diff --git a/gen_rangefunc.go b/gen_rangefunc.go index 0bc4319..98b0a3c 100644 --- a/gen_rangefunc.go +++ b/gen_rangefunc.go @@ -12,237 +12,296 @@ import ( ) func All[T any](seq iter.Seq[T], f func(T) bool) bool { - return _All(seq, f) + _r0 := _All(_Seq[T](seq), f) + return _r0 } func Any[T any](seq iter.Seq[T], f func(T) bool) bool { - return _Any(seq, f) + _r0 := _Any(_Seq[T](seq), f) + return _r0 } func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1, []T2) { - return _AppendSplitTo(seq, s1, s2) + _r0, _r1 := _AppendSplitTo(seq, s1, s2) + return _r0, _r1 } func AppendTo[T any, S ~[]T](seq iter.Seq[T], s S) S { - return _AppendTo(seq, s) + _r0 := _AppendTo(_Seq[T](seq), s) + return _r0 } func Bytes(s string) iter.Seq[byte] { - return _Bytes(s) + _r0 := _Bytes(s) + return iter.Seq[byte](_r0) } func Cache[T any](seq iter.Seq[T]) iter.Seq[T] { - return _Cache(seq) + _r0 := _Cache(_Seq[T](seq)) + return iter.Seq[T](_r0) } func Chunks[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { - return _Chunks(seq, n) + _r0 := _Chunks(_Seq[T](seq), n) + return iter.Seq[[]T](_r0) } func Collect[T any](seq iter.Seq[T]) []T { - return _Collect(seq) + _r0 := _Collect(_Seq[T](seq)) + return _r0 } func CollectSize[T any](seq iter.Seq[T], len int) []T { - return _CollectSize(seq, len) + _r0 := _CollectSize(_Seq[T](seq), len) + return _r0 } func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { - return _CollectSplit(seq) + _r0, _r1 := _CollectSplit(seq) + return _r0, _r1 } func Concat[T any](seqs []iter.Seq[T]) iter.Seq[T] { - return _Concat(seqs) + _r0 := _Concat(seqs) + return iter.Seq[T](_r0) } func Contains[T comparable](seq iter.Seq[T], v T) bool { - return _Contains(seq, v) + _r0 := _Contains(_Seq[T](seq), v) + return _r0 } func Drain[T any](seq iter.Seq[T]) { - return _Drain(seq) + _Drain(_Seq[T](seq)) + } func Enumerate[T any](seq iter.Seq[T]) iter.Seq2[int, T] { - return _Enumerate(seq) + _r0 := _Enumerate(_Seq[T](seq)) + return iter.Seq2[int, T](_r0) } func Equal[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) bool { - return _Equal(seq1, seq2) + _r0 := _Equal(_Seq[T](seq1), _Seq[T](seq2)) + return _r0 } func EqualFunc[T1 any, T2 any](seq1 iter.Seq[T1], seq2 iter.Seq[T2], equal func(T1, T2) bool) bool { - return _EqualFunc(seq1, seq2, equal) + _r0 := _EqualFunc(_Seq[T1](seq1), _Seq[T2](seq2), equal) + return _r0 } func Filter[T any](seq iter.Seq[T], f func(T) bool) iter.Seq[T] { - return _Filter(seq, f) + _r0 := _Filter(_Seq[T](seq), f) + return iter.Seq[T](_r0) } func Find[T any](seq iter.Seq[T], f func(T) bool) (r T, ok bool) { - return _Find(seq, f) + _r0, _r1 := _Find(_Seq[T](seq), f) + return _r0, _r1 } func Flatten[T any](seq iter.Seq[iter.Seq[T]]) iter.Seq[T] { - return _Flatten(seq) + _r0 := _Flatten(_Seq[iter.Seq[T]](seq)) + return iter.Seq[T](_r0) } func Fold[T any](seq iter.Seq[T], reducer func(T, T) T) T { - return _Fold(seq, reducer) + _r0 := _Fold(_Seq[T](seq), reducer) + return _r0 } func FromPair[T1 any, T2 any](seq iter.Seq[Pair[T1, T2]]) iter.Seq2[T1, T2] { - return _FromPair(seq) + _r0 := _FromPair(_Seq[Pair[T1, T2]](seq)) + return iter.Seq2[T1, T2](_r0) } func Generate[T Addable](start T, step T) iter.Seq[T] { - return _Generate(start, step) + _r0 := _Generate(start, step) + return iter.Seq[T](_r0) } func GoPull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { - return _GoPull(seq) + _r0, _r1 := _GoPull(_Seq[T](seq)) + return _r0, _r1 } func Handle[T any](seq iter.Seq2[T, error], f func(error) bool) iter.Seq[T] { - return _Handle(seq, f) + _r0 := _Handle(_Seq2[T, error](seq), f) + return iter.Seq[T](_r0) } func IsSorted[T cmp.Ordered](seq iter.Seq[T]) bool { - return _IsSorted(seq) + _r0 := _IsSorted(_Seq[T](seq)) + return _r0 } func IsSortedFunc[T any](seq iter.Seq[T], compare func(T, T) int) bool { - return _IsSortedFunc(seq, compare) + _r0 := _IsSortedFunc(_Seq[T](seq), compare) + return _r0 } func Limit[T any](seq iter.Seq[T], n int) iter.Seq[T] { - return _Limit(seq, n) + _r0 := _Limit(_Seq[T](seq), n) + return iter.Seq[T](_r0) } func Map[T1 any, T2 any](seq iter.Seq[T1], f func(T1) T2) iter.Seq[T2] { - return _Map(seq, f) + _r0 := _Map(_Seq[T1](seq), f) + return iter.Seq[T2](_r0) } func MapKeys[K comparable, V any, M ~map[K]V](m M) iter.Seq[K] { - return _MapKeys(m) + _r0 := _MapKeys(m) + return iter.Seq[K](_r0) } func MapValues[K comparable, V any, M ~map[K]V](m M) iter.Seq[V] { - return _MapValues(m) + _r0 := _MapValues(m) + return iter.Seq[V](_r0) } func Max[T cmp.Ordered](seq iter.Seq[T]) T { - return _Max(seq) + _r0 := _Max(_Seq[T](seq)) + return _r0 } func Merge[T cmp.Ordered](seq1 iter.Seq[T], seq2 iter.Seq[T]) iter.Seq[T] { - return _Merge(seq1, seq2) + _r0 := _Merge(_Seq[T](seq1), _Seq[T](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] { - return _MergeFunc(seq1, seq2, compare) + _r0 := _MergeFunc(_Seq[T](seq1), _Seq[T](seq2), compare) + return iter.Seq[T](_r0) } func Min[T cmp.Ordered](seq iter.Seq[T]) T { - return _Min(seq) + _r0 := _Min(_Seq[T](seq)) + return _r0 } func Of[T any](vals []T) iter.Seq[T] { - return _Of(vals) + _r0 := _Of(vals) + return iter.Seq[T](_r0) } func OfChan[T any](c <-chan T) iter.Seq[T] { - return _OfChan(c) + _r0 := _OfChan(c) + return iter.Seq[T](_r0) } func OfMap[K comparable, V any, M ~map[K]V](m M) iter.Seq2[K, V] { - return _OfMap(m) + _r0 := _OfMap(m) + return iter.Seq2[K, V](_r0) } func OfSlice[T any, S ~[]T](s S) iter.Seq[T] { - return _OfSlice(s) + _r0 := _OfSlice(s) + return iter.Seq[T](_r0) } func OfSliceIndex[T any, S ~[]T](s S) iter.Seq2[int, T] { - return _OfSliceIndex(s) + _r0 := _OfSliceIndex(s) + return iter.Seq2[int, T](_r0) } func OfValue(v reflect.Value) iter.Seq2[reflect.Value, reflect.Value] { - return _OfValue(v) + _r0 := _OfValue(v) + return iter.Seq2[reflect.Value, reflect.Value](_r0) } func Or[T any](seqs []iter.Seq[T]) iter.Seq[T] { - return _Or(seqs) + _r0 := _Or(seqs) + return iter.Seq[T](_r0) } func Partition[T any](seq iter.Seq[T], f func(T) bool) (true []T, false []T) { - return _Partition(seq, f) + _r0, _r1 := _Partition(_Seq[T](seq), f) + return _r0, _r1 } func PartitionInto[T any](seq iter.Seq[T], f func(T) bool, true []T, false []T) ([]T, []T) { - return _PartitionInto(seq, f, true, false) + _r0, _r1 := _PartitionInto(_Seq[T](seq), f, true, false) + return _r0, _r1 } func Product[T Multiplyable](seq iter.Seq[T]) T { - return _Product(seq) + _r0 := _Product(_Seq[T](seq)) + return _r0 } func Pull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { - return _Pull(seq) + _r0, _r1 := _Pull(_Seq[T](seq)) + return _r0, _r1 } func RecvContext[T any](ctx context.Context, c <-chan T) iter.Seq[T] { - return _RecvContext(ctx, c) + _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 { - return _Reduce(seq, initial, reducer) + _r0 := _Reduce(_Seq[T](seq), initial, reducer) + return _r0 } func Runes[T ~[]byte | ~string](s T) iter.Seq[rune] { - return _Runes(s) + _r0 := _Runes(s) + return iter.Seq[rune](_r0) } func SendContext[T any](seq iter.Seq[T], ctx context.Context, c chan<- T) { - return _SendContext(seq, ctx, c) + _SendContext(_Seq[T](seq), ctx, c) + } func Skip[T any](seq iter.Seq[T], n int) iter.Seq[T] { - return _Skip(seq, n) + _r0 := _Skip(_Seq[T](seq), n) + return iter.Seq[T](_r0) } func Split[T any](seq iter.Seq[T], f func(T) bool) SplitSeq[T, T] { - return _Split(seq, f) + _r0 := _Split(_Seq[T](seq), f) + return _r0 } func Split2[T1 any, T2 any](seq iter.Seq2[T1, T2]) SplitSeq[T1, T2] { - return _Split2(seq) + _r0 := _Split2(_Seq2[T1, T2](seq)) + return _r0 } func StringSplit(s string, sep string) iter.Seq[string] { - return _StringSplit(s, sep) + _r0 := _StringSplit(s, sep) + return iter.Seq[string](_r0) } func Sum[T Addable](seq iter.Seq[T]) T { - return _Sum(seq) + _r0 := _Sum(_Seq[T](seq)) + return _r0 } func ToPair[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[Pair[T1, T2]] { - return _ToPair(seq) + _r0 := _ToPair(_Seq2[T1, T2](seq)) + return iter.Seq[Pair[T1, T2]](_r0) } func V1[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T1] { - return _V1(seq) + _r0 := _V1(_Seq2[T1, T2](seq)) + return iter.Seq[T1](_r0) } func V2[T1 any, T2 any](seq iter.Seq2[T1, T2]) iter.Seq[T2] { - return _V2(seq) + _r0 := _V2(_Seq2[T1, T2](seq)) + return iter.Seq[T2](_r0) } func Windows[T any](seq iter.Seq[T], n int) iter.Seq[[]T] { - return _Windows(seq, n) + _r0 := _Windows(_Seq[T](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]] { - return _Zip(seq1, seq2) + _r0 := _Zip(_Seq[T1](seq1), _Seq[T2](seq2)) + return iter.Seq[Zipped[T1, T2]](_r0) } diff --git a/internal/gen/gen.go b/internal/gen/gen.go index 4cdb7e6..447f0fa 100644 --- a/internal/gen/gen.go +++ b/internal/gen/gen.go @@ -24,10 +24,12 @@ var ( outputTemplate string tmpl = template.Must(template.New("output").Funcs(funcMap).Parse(outputTemplate)) funcMap = map[string]any{ - "convertFuncName": convertFuncName, "typeParamSlice": listToSlice[*types.TypeParam], "tupleSlice": listToSlice[*types.Var], + "convertFuncName": convertFuncName, "convertType": convertType, + "convertArg": convertArg, + "convertReturn": convertReturn, } ) @@ -93,6 +95,63 @@ func convertTypeName(rangefunc bool, name string) string { return "iter." + cut } +func convertArg(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 := t.Obj().Name() + if !strings.HasPrefix(tname, "_") { + return name + } + + 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, arg)) + } + return fmt.Sprintf("%v[%v](%v)", tname, strings.Join(typeArgs, ","), 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, arg)) + } + return fmt.Sprintf("%v[%v](%v)", tname, strings.Join(typeArgs, ","), name) + + default: + return name + } +} + func load() []*types.Func { config := packages.Config{Mode: packages.NeedTypes | packages.NeedTypesInfo} pkgs, err := packages.Load(&config, "deedles.dev/xiter") diff --git a/internal/gen/output.go.tmpl b/internal/gen/output.go.tmpl index ec80e1e..2633ba6 100644 --- a/internal/gen/output.go.tmpl +++ b/internal/gen/output.go.tmpl @@ -25,10 +25,11 @@ import ( {{- .Name}} {{.Type | convertType $.RangeFunc}}, {{- end -}} ) { - return {{.Name}}( - {{- range .Type.Params | tupleSlice}} - {{- .Name }}, + {{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 }}, {{- 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}} From 7fff859edb772fc81c2b913d20c6550a90669e4e Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 17:06:09 -0500 Subject: [PATCH 11/15] internal/xslices: add --- internal/xslices/xslices.go | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 internal/xslices/xslices.go diff --git a/internal/xslices/xslices.go b/internal/xslices/xslices.go new file mode 100644 index 0000000..dc00571 --- /dev/null +++ b/internal/xslices/xslices.go @@ -0,0 +1,9 @@ +package xslices + +func Map[From, To any](from []From, f func(From) To) []To { + to := make([]To, 0, len(from)) + for _, v := range from { + to = append(to, f(v)) + } + return to +} From 5103d44e6256dabf0f6c72061551f4c3e74aabb7 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Tue, 16 Jan 2024 17:07:47 -0500 Subject: [PATCH 12/15] internal/gen: get everything working except for `Flatten()` --- gen_norangefunc.go | 10 +++++---- gen_rangefunc.go | 9 ++++---- internal/gen/gen.go | 42 +++++++++++++++++++++++++++---------- internal/gen/output.go.tmpl | 5 +++-- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/gen_norangefunc.go b/gen_norangefunc.go index 224e627..ff5fe2b 100644 --- a/gen_norangefunc.go +++ b/gen_norangefunc.go @@ -8,6 +8,8 @@ import ( "cmp" "context" "reflect" + + "deedles.dev/xiter/internal/xslices" ) func All[T any](seq Seq[T], f func(T) bool) bool { @@ -61,7 +63,7 @@ func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { } func Concat[T any](seqs []Seq[T]) Seq[T] { - _r0 := _Concat(seqs) + _r0 := _Concat(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) return Seq[T](_r0) } @@ -101,7 +103,7 @@ func Find[T any](seq Seq[T], f func(T) bool) (r T, ok bool) { } func Flatten[T any](seq Seq[Seq[T]]) Seq[T] { - _r0 := _Flatten(_Seq[Seq[T]](seq)) + _r0 := _Flatten(_Seq[_Seq[T]](seq)) return Seq[T](_r0) } @@ -181,7 +183,7 @@ func Min[T cmp.Ordered](seq Seq[T]) T { } func Of[T any](vals []T) Seq[T] { - _r0 := _Of(vals) + _r0 := _Of(vals...) return Seq[T](_r0) } @@ -211,7 +213,7 @@ func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { } func Or[T any](seqs []Seq[T]) Seq[T] { - _r0 := _Or(seqs) + _r0 := _Or(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) return Seq[T](_r0) } diff --git a/gen_rangefunc.go b/gen_rangefunc.go index 98b0a3c..c919eea 100644 --- a/gen_rangefunc.go +++ b/gen_rangefunc.go @@ -7,6 +7,7 @@ package xiter import ( "cmp" "context" + "deedles.dev/xiter/internal/xslices" "iter" "reflect" ) @@ -62,7 +63,7 @@ func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { } func Concat[T any](seqs []iter.Seq[T]) iter.Seq[T] { - _r0 := _Concat(seqs) + _r0 := _Concat(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) return iter.Seq[T](_r0) } @@ -102,7 +103,7 @@ func Find[T any](seq iter.Seq[T], f func(T) bool) (r T, ok bool) { } func Flatten[T any](seq iter.Seq[iter.Seq[T]]) iter.Seq[T] { - _r0 := _Flatten(_Seq[iter.Seq[T]](seq)) + _r0 := _Flatten(_Seq[_Seq[T]](seq)) return iter.Seq[T](_r0) } @@ -182,7 +183,7 @@ func Min[T cmp.Ordered](seq iter.Seq[T]) T { } func Of[T any](vals []T) iter.Seq[T] { - _r0 := _Of(vals) + _r0 := _Of(vals...) return iter.Seq[T](_r0) } @@ -212,7 +213,7 @@ func OfValue(v reflect.Value) iter.Seq2[reflect.Value, reflect.Value] { } func Or[T any](seqs []iter.Seq[T]) iter.Seq[T] { - _r0 := _Or(seqs) + _r0 := _Or(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) return iter.Seq[T](_r0) } diff --git a/internal/gen/gen.go b/internal/gen/gen.go index 447f0fa..96f919e 100644 --- a/internal/gen/gen.go +++ b/internal/gen/gen.go @@ -95,27 +95,47 @@ func convertTypeName(rangefunc bool, name string) string { return "iter." + cut } -func convertArg(rangefunc bool, t types.Type, name string) string { +func convertArgType(rangefunc bool, t types.Type) (from string, to string, 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 name + return t.String(), t.String(), false } - tname := t.Obj().Name() - if !strings.HasPrefix(tname, "_") { - return name + 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, ",")) } - if t.TypeArgs().Len() == 0 { - return fmt.Sprintf("%v(%v)", tname, name) + from, ok := strings.CutPrefix(to, "_") + return from, to, ok + + default: + return t.String(), t.String(), false + } +} + +func convertArg(rangefunc bool, t types.Type, name string) string { + switch t := t.(type) { + case *types.Named: + _, to, ok := convertArgType(rangefunc, t) + if !ok { + return name } + return fmt.Sprintf("%v(%v)", to, name) - typeArgs := make([]string, 0, t.TypeArgs().Len()) - for _, arg := range listToSlice(t.TypeArgs()) { - typeArgs = append(typeArgs, convertType(rangefunc, arg)) + case *types.Slice: + from, to, ok := convertArgType(rangefunc, t.Elem()) + if !ok { + return name } - return fmt.Sprintf("%v[%v](%v)", tname, strings.Join(typeArgs, ","), name) + return fmt.Sprintf("xslices.Map(%v, func(v %v) %v { return %v(v) })", name, from, to, to) default: return name diff --git a/internal/gen/output.go.tmpl b/internal/gen/output.go.tmpl index 2633ba6..c229d46 100644 --- a/internal/gen/output.go.tmpl +++ b/internal/gen/output.go.tmpl @@ -9,9 +9,10 @@ import ( "context" "reflect" {{if .RangeFunc}}"iter"{{end}} + "deedles.dev/xiter/internal/xslices" ) -{{range .Funcs}} +{{range $func := .Funcs}} func {{.Name | convertFuncName}}{{with .Type.TypeParams | typeParamSlice}}[ {{- range .}} {{- .}} {{.Constraint | convertType $.RangeFunc}}, @@ -27,7 +28,7 @@ import ( ) { {{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 }}, + {{- .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}} From 887978d1e05124445d147b8c7b3cb84221ebb287 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Fri, 2 Feb 2024 17:40:15 -0500 Subject: [PATCH 13/15] internal/gen: fix variadic functions and slice conversion --- gen_norangefunc.go | 15 +++++++-------- gen_rangefunc.go | 14 +++++++------- internal/gen/gen.go | 27 +++++++++++++++++++-------- internal/gen/output.go.tmpl | 14 +++++++------- 4 files changed, 40 insertions(+), 30 deletions(-) diff --git a/gen_norangefunc.go b/gen_norangefunc.go index ff5fe2b..ee597dc 100644 --- a/gen_norangefunc.go +++ b/gen_norangefunc.go @@ -1,6 +1,6 @@ // Code generated by internal/gen. DO NOT EDIT. -//go:build !rangefunc +//go:build !goexperiment.rangefunc package xiter @@ -8,8 +8,7 @@ import ( "cmp" "context" "reflect" - - "deedles.dev/xiter/internal/xslices" + "unsafe" ) func All[T any](seq Seq[T], f func(T) bool) bool { @@ -62,8 +61,8 @@ func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { return _r0, _r1 } -func Concat[T any](seqs []Seq[T]) Seq[T] { - _r0 := _Concat(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) +func Concat[T any](seqs ...Seq[T]) Seq[T] { + _r0 := _Concat(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) return Seq[T](_r0) } @@ -182,7 +181,7 @@ func Min[T cmp.Ordered](seq Seq[T]) T { return _r0 } -func Of[T any](vals []T) Seq[T] { +func Of[T any](vals ...T) Seq[T] { _r0 := _Of(vals...) return Seq[T](_r0) } @@ -212,8 +211,8 @@ func OfValue(v reflect.Value) Seq2[reflect.Value, reflect.Value] { return Seq2[reflect.Value, reflect.Value](_r0) } -func Or[T any](seqs []Seq[T]) Seq[T] { - _r0 := _Or(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) +func Or[T any](seqs ...Seq[T]) Seq[T] { + _r0 := _Or(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) return Seq[T](_r0) } diff --git a/gen_rangefunc.go b/gen_rangefunc.go index c919eea..c918690 100644 --- a/gen_rangefunc.go +++ b/gen_rangefunc.go @@ -1,15 +1,15 @@ // Code generated by internal/gen. DO NOT EDIT. -//go:build rangefunc +//go:build goexperiment.rangefunc package xiter import ( "cmp" "context" - "deedles.dev/xiter/internal/xslices" "iter" "reflect" + "unsafe" ) func All[T any](seq iter.Seq[T], f func(T) bool) bool { @@ -62,8 +62,8 @@ func CollectSplit[T1 any, T2 any](seq SplitSeq[T1, T2]) (y1 []T1, y2 []T2) { return _r0, _r1 } -func Concat[T any](seqs []iter.Seq[T]) iter.Seq[T] { - _r0 := _Concat(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) +func Concat[T any](seqs ...iter.Seq[T]) iter.Seq[T] { + _r0 := _Concat(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) return iter.Seq[T](_r0) } @@ -182,7 +182,7 @@ func Min[T cmp.Ordered](seq iter.Seq[T]) T { return _r0 } -func Of[T any](vals []T) iter.Seq[T] { +func Of[T any](vals ...T) iter.Seq[T] { _r0 := _Of(vals...) return iter.Seq[T](_r0) } @@ -212,8 +212,8 @@ func OfValue(v reflect.Value) iter.Seq2[reflect.Value, reflect.Value] { return iter.Seq2[reflect.Value, reflect.Value](_r0) } -func Or[T any](seqs []iter.Seq[T]) iter.Seq[T] { - _r0 := _Or(xslices.Map(seqs, func(v Seq[T]) _Seq[T] { return _Seq[T](v) })...) +func Or[T any](seqs ...iter.Seq[T]) iter.Seq[T] { + _r0 := _Or(*(*[]_Seq[T])(unsafe.Pointer(&seqs))...) return iter.Seq[T](_r0) } diff --git a/internal/gen/gen.go b/internal/gen/gen.go index 96f919e..f8eb144 100644 --- a/internal/gen/gen.go +++ b/internal/gen/gen.go @@ -4,6 +4,7 @@ import ( "bytes" "cmp" _ "embed" + "flag" "fmt" "go/format" "go/types" @@ -51,7 +52,7 @@ func listToSlice[T any](list List[T]) []T { return s } -func convertType(rangefunc bool, t types.Type) string { +func convertType(rangefunc bool, variadic bool, t types.Type) string { switch t := t.(type) { case *types.Named: var pkg string @@ -67,12 +68,16 @@ func convertType(rangefunc bool, t types.Type) string { typeArgs := make([]string, 0, t.TypeArgs().Len()) for _, arg := range listToSlice(t.TypeArgs()) { - typeArgs = append(typeArgs, convertType(rangefunc, arg)) + typeArgs = append(typeArgs, convertType(rangefunc, false, arg)) } return fmt.Sprintf("%v%v[%v]", pkg, name, strings.Join(typeArgs, ",")) case *types.Slice: - return fmt.Sprintf("[]%v", convertType(rangefunc, t.Elem())) + ct := convertType(rangefunc, false, t.Elem()) + if variadic { + return fmt.Sprintf("...%v", ct) + } + return fmt.Sprintf("[]%v", ct) case *types.Interface, *types.Basic, *types.TypeParam, *types.Signature, *types.Chan: return t.String() @@ -131,11 +136,11 @@ func convertArg(rangefunc bool, t types.Type, name string) string { return fmt.Sprintf("%v(%v)", to, name) case *types.Slice: - from, to, ok := convertArgType(rangefunc, t.Elem()) + _, to, ok := convertArgType(rangefunc, t.Elem()) if !ok { return name } - return fmt.Sprintf("xslices.Map(%v, func(v %v) %v { return %v(v) })", name, from, to, to) + return fmt.Sprintf("*(*[]%v)(unsafe.Pointer(&%v))", to, name) default: return name @@ -163,7 +168,7 @@ func convertReturn(rangefunc bool, t types.Type, name string) string { typeArgs := make([]string, 0, t.TypeArgs().Len()) for _, arg := range listToSlice(t.TypeArgs()) { - typeArgs = append(typeArgs, convertType(rangefunc, arg)) + typeArgs = append(typeArgs, convertType(rangefunc, false, arg)) } return fmt.Sprintf("%v[%v](%v)", tname, strings.Join(typeArgs, ","), name) @@ -172,7 +177,7 @@ func convertReturn(rangefunc bool, t types.Type, name string) string { } } -func load() []*types.Func { +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 { @@ -186,6 +191,9 @@ func load() []*types.Func { if !ok { continue } + if slices.Contains(ignore, f.Name()) { + continue + } if !namePattern.MatchString(f.Name()) { continue } @@ -224,7 +232,10 @@ func write(name string, funcs []*types.Func, rangefunc bool) { } func main() { - funcs := load() + 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 index c229d46..493b0c4 100644 --- a/internal/gen/output.go.tmpl +++ b/internal/gen/output.go.tmpl @@ -1,6 +1,6 @@ // Code generated by internal/gen. DO NOT EDIT. -//go:build {{if not .RangeFunc}}!{{end}}rangefunc +//go:build {{if not .RangeFunc}}!{{end}}goexperiment.rangefunc package xiter @@ -8,27 +8,27 @@ import ( "cmp" "context" "reflect" + "unsafe" {{if .RangeFunc}}"iter"{{end}} - "deedles.dev/xiter/internal/xslices" ) {{range $func := .Funcs}} func {{.Name | convertFuncName}}{{with .Type.TypeParams | typeParamSlice}}[ {{- range .}} - {{- .}} {{.Constraint | convertType $.RangeFunc}}, + {{- .}} {{.Constraint | convertType $.RangeFunc false}}, {{- end -}} ]{{end}}( - {{- range .Type.Params | tupleSlice}} - {{- .Name}} {{.Type | convertType $.RangeFunc}}, + {{- 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}}, + {{- .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}}, + {{- .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}} From 35c14bfc26cfe96d6c9dddb81bf0bc9cff302c93 Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Fri, 2 Feb 2024 17:40:41 -0500 Subject: [PATCH 14/15] internal/xslices: remove --- internal/xslices/xslices.go | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 internal/xslices/xslices.go diff --git a/internal/xslices/xslices.go b/internal/xslices/xslices.go deleted file mode 100644 index dc00571..0000000 --- a/internal/xslices/xslices.go +++ /dev/null @@ -1,9 +0,0 @@ -package xslices - -func Map[From, To any](from []From, f func(From) To) []To { - to := make([]To, 0, len(from)) - for _, v := range from { - to = append(to, f(v)) - } - return to -} From cf144b8fab7fca8c6668514c8382903293139e9a Mon Sep 17 00:00:00 2001 From: DeedleFake Date: Fri, 2 Feb 2024 17:46:50 -0500 Subject: [PATCH 15/15] internal/gen: fix last necessary edge case --- gen_norangefunc.go | 84 ++++++++++++++++++++++----------------------- gen_rangefunc.go | 84 ++++++++++++++++++++++----------------------- internal/gen/gen.go | 21 +++++++----- transform_test.go | 64 +++++++++++++++++----------------- 4 files changed, 129 insertions(+), 124 deletions(-) diff --git a/gen_norangefunc.go b/gen_norangefunc.go index ee597dc..3587e57 100644 --- a/gen_norangefunc.go +++ b/gen_norangefunc.go @@ -12,12 +12,12 @@ import ( ) func All[T any](seq Seq[T], f func(T) bool) bool { - _r0 := _All(_Seq[T](seq), f) + _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](seq), f) + _r0 := _Any(*(*_Seq[T])(unsafe.Pointer(&seq)), f) return _r0 } @@ -27,7 +27,7 @@ func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1 } func AppendTo[T any, S ~[]T](seq Seq[T], s S) S { - _r0 := _AppendTo(_Seq[T](seq), s) + _r0 := _AppendTo(*(*_Seq[T])(unsafe.Pointer(&seq)), s) return _r0 } @@ -37,22 +37,22 @@ func Bytes(s string) Seq[byte] { } func Cache[T any](seq Seq[T]) Seq[T] { - _r0 := _Cache(_Seq[T](seq)) + _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](seq), n) + _r0 := _Chunks(*(*_Seq[T])(unsafe.Pointer(&seq)), n) return Seq[[]T](_r0) } func Collect[T any](seq Seq[T]) []T { - _r0 := _Collect(_Seq[T](seq)) + _r0 := _Collect(*(*_Seq[T])(unsafe.Pointer(&seq))) return _r0 } func CollectSize[T any](seq Seq[T], len int) []T { - _r0 := _CollectSize(_Seq[T](seq), len) + _r0 := _CollectSize(*(*_Seq[T])(unsafe.Pointer(&seq)), len) return _r0 } @@ -67,52 +67,52 @@ func Concat[T any](seqs ...Seq[T]) Seq[T] { } func Contains[T comparable](seq Seq[T], v T) bool { - _r0 := _Contains(_Seq[T](seq), v) + _r0 := _Contains(*(*_Seq[T])(unsafe.Pointer(&seq)), v) return _r0 } func Drain[T any](seq Seq[T]) { - _Drain(_Seq[T](seq)) + _Drain(*(*_Seq[T])(unsafe.Pointer(&seq))) } func Enumerate[T any](seq Seq[T]) Seq2[int, T] { - _r0 := _Enumerate(_Seq[T](seq)) + _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](seq1), _Seq[T](seq2)) + _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](seq1), _Seq[T2](seq2), equal) + _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](seq), f) + _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](seq), f) + _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]](seq)) + _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](seq), reducer) + _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]](seq)) + _r0 := _FromPair(*(*_Seq[Pair[T1, T2]])(unsafe.Pointer(&seq))) return Seq2[T1, T2](_r0) } @@ -122,32 +122,32 @@ func Generate[T Addable](start T, step T) Seq[T] { } func GoPull[T any](seq Seq[T]) (iter func() (T, bool), stop func()) { - _r0, _r1 := _GoPull(_Seq[T](seq)) + _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](seq), f) + _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](seq)) + _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](seq), compare) + _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](seq), n) + _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](seq), f) + _r0 := _Map(*(*_Seq[T1])(unsafe.Pointer(&seq)), f) return Seq[T2](_r0) } @@ -162,22 +162,22 @@ func MapValues[K comparable, V any, M ~map[K]V](m M) Seq[V] { } func Max[T cmp.Ordered](seq Seq[T]) T { - _r0 := _Max(_Seq[T](seq)) + _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](seq1), _Seq[T](seq2)) + _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](seq1), _Seq[T](seq2), compare) + _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](seq)) + _r0 := _Min(*(*_Seq[T])(unsafe.Pointer(&seq))) return _r0 } @@ -217,22 +217,22 @@ func Or[T any](seqs ...Seq[T]) Seq[T] { } func Partition[T any](seq Seq[T], f func(T) bool) (true []T, false []T) { - _r0, _r1 := _Partition(_Seq[T](seq), f) + _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](seq), f, true, false) + _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](seq)) + _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](seq)) + _r0, _r1 := _Pull(*(*_Seq[T])(unsafe.Pointer(&seq))) return _r0, _r1 } @@ -242,7 +242,7 @@ func RecvContext[T any](ctx context.Context, c <-chan T) Seq[T] { } func Reduce[T any, R any](seq Seq[T], initial R, reducer func(R, T) R) R { - _r0 := _Reduce(_Seq[T](seq), initial, reducer) + _r0 := _Reduce(*(*_Seq[T])(unsafe.Pointer(&seq)), initial, reducer) return _r0 } @@ -252,22 +252,22 @@ func Runes[T ~[]byte | ~string](s T) Seq[rune] { } func SendContext[T any](seq Seq[T], ctx context.Context, c chan<- T) { - _SendContext(_Seq[T](seq), ctx, c) + _SendContext(*(*_Seq[T])(unsafe.Pointer(&seq)), ctx, c) } func Skip[T any](seq Seq[T], n int) Seq[T] { - _r0 := _Skip(_Seq[T](seq), n) + _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](seq), f) + _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](seq)) + _r0 := _Split2(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) return _r0 } @@ -277,31 +277,31 @@ func StringSplit(s string, sep string) Seq[string] { } func Sum[T Addable](seq Seq[T]) T { - _r0 := _Sum(_Seq[T](seq)) + _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](seq)) + _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](seq)) + _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](seq)) + _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](seq), n) + _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](seq1), _Seq[T2](seq2)) + _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 index c918690..1cf05e6 100644 --- a/gen_rangefunc.go +++ b/gen_rangefunc.go @@ -13,12 +13,12 @@ import ( ) func All[T any](seq iter.Seq[T], f func(T) bool) bool { - _r0 := _All(_Seq[T](seq), f) + _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](seq), f) + _r0 := _Any(*(*_Seq[T])(unsafe.Pointer(&seq)), f) return _r0 } @@ -28,7 +28,7 @@ func AppendSplitTo[T1 any, T2 any](seq SplitSeq[T1, T2], s1 []T1, s2 []T2) ([]T1 } func AppendTo[T any, S ~[]T](seq iter.Seq[T], s S) S { - _r0 := _AppendTo(_Seq[T](seq), s) + _r0 := _AppendTo(*(*_Seq[T])(unsafe.Pointer(&seq)), s) return _r0 } @@ -38,22 +38,22 @@ func Bytes(s string) iter.Seq[byte] { } func Cache[T any](seq iter.Seq[T]) iter.Seq[T] { - _r0 := _Cache(_Seq[T](seq)) + _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](seq), n) + _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](seq)) + _r0 := _Collect(*(*_Seq[T])(unsafe.Pointer(&seq))) return _r0 } func CollectSize[T any](seq iter.Seq[T], len int) []T { - _r0 := _CollectSize(_Seq[T](seq), len) + _r0 := _CollectSize(*(*_Seq[T])(unsafe.Pointer(&seq)), len) return _r0 } @@ -68,52 +68,52 @@ func Concat[T any](seqs ...iter.Seq[T]) iter.Seq[T] { } func Contains[T comparable](seq iter.Seq[T], v T) bool { - _r0 := _Contains(_Seq[T](seq), v) + _r0 := _Contains(*(*_Seq[T])(unsafe.Pointer(&seq)), v) return _r0 } func Drain[T any](seq iter.Seq[T]) { - _Drain(_Seq[T](seq)) + _Drain(*(*_Seq[T])(unsafe.Pointer(&seq))) } func Enumerate[T any](seq iter.Seq[T]) iter.Seq2[int, T] { - _r0 := _Enumerate(_Seq[T](seq)) + _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](seq1), _Seq[T](seq2)) + _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](seq1), _Seq[T2](seq2), equal) + _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](seq), f) + _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](seq), f) + _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]](seq)) + _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](seq), reducer) + _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]](seq)) + _r0 := _FromPair(*(*_Seq[Pair[T1, T2]])(unsafe.Pointer(&seq))) return iter.Seq2[T1, T2](_r0) } @@ -123,32 +123,32 @@ func Generate[T Addable](start T, step T) iter.Seq[T] { } func GoPull[T any](seq iter.Seq[T]) (iter func() (T, bool), stop func()) { - _r0, _r1 := _GoPull(_Seq[T](seq)) + _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](seq), f) + _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](seq)) + _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](seq), compare) + _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](seq), n) + _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](seq), f) + _r0 := _Map(*(*_Seq[T1])(unsafe.Pointer(&seq)), f) return iter.Seq[T2](_r0) } @@ -163,22 +163,22 @@ func MapValues[K comparable, V any, M ~map[K]V](m M) iter.Seq[V] { } func Max[T cmp.Ordered](seq iter.Seq[T]) T { - _r0 := _Max(_Seq[T](seq)) + _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](seq1), _Seq[T](seq2)) + _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](seq1), _Seq[T](seq2), compare) + _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](seq)) + _r0 := _Min(*(*_Seq[T])(unsafe.Pointer(&seq))) return _r0 } @@ -218,22 +218,22 @@ func Or[T any](seqs ...iter.Seq[T]) iter.Seq[T] { } func Partition[T any](seq iter.Seq[T], f func(T) bool) (true []T, false []T) { - _r0, _r1 := _Partition(_Seq[T](seq), f) + _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](seq), f, true, false) + _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](seq)) + _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](seq)) + _r0, _r1 := _Pull(*(*_Seq[T])(unsafe.Pointer(&seq))) return _r0, _r1 } @@ -243,7 +243,7 @@ func RecvContext[T any](ctx context.Context, c <-chan T) iter.Seq[T] { } func Reduce[T any, R any](seq iter.Seq[T], initial R, reducer func(R, T) R) R { - _r0 := _Reduce(_Seq[T](seq), initial, reducer) + _r0 := _Reduce(*(*_Seq[T])(unsafe.Pointer(&seq)), initial, reducer) return _r0 } @@ -253,22 +253,22 @@ func Runes[T ~[]byte | ~string](s T) iter.Seq[rune] { } func SendContext[T any](seq iter.Seq[T], ctx context.Context, c chan<- T) { - _SendContext(_Seq[T](seq), ctx, c) + _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](seq), n) + _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](seq), f) + _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](seq)) + _r0 := _Split2(*(*_Seq2[T1, T2])(unsafe.Pointer(&seq))) return _r0 } @@ -278,31 +278,31 @@ func StringSplit(s string, sep string) iter.Seq[string] { } func Sum[T Addable](seq iter.Seq[T]) T { - _r0 := _Sum(_Seq[T](seq)) + _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](seq)) + _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](seq)) + _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](seq)) + _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](seq), n) + _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](seq1), _Seq[T2](seq2)) + _r0 := _Zip(*(*_Seq[T1])(unsafe.Pointer(&seq1)), *(*_Seq[T2])(unsafe.Pointer(&seq2))) return iter.Seq[Zipped[T1, T2]](_r0) } diff --git a/internal/gen/gen.go b/internal/gen/gen.go index f8eb144..75789ec 100644 --- a/internal/gen/gen.go +++ b/internal/gen/gen.go @@ -75,6 +75,8 @@ func convertType(rangefunc bool, variadic bool, t types.Type) string { 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) @@ -100,43 +102,46 @@ func convertTypeName(rangefunc bool, name string) string { return "iter." + cut } -func convertArgType(rangefunc bool, t types.Type) (from string, to string, ok bool) { +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 + 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) + _, 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, ok + return from, to, t.TypeArgs().Len() != 0, ok default: - return t.String(), t.String(), false + 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, ok := convertArgType(rangefunc, t) + _, to, unsafe, ok := convertArgType(rangefunc, t) if !ok { return name } - return fmt.Sprintf("%v(%v)", to, 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()) + _, to, _, ok := convertArgType(rangefunc, t.Elem()) if !ok { return name } diff --git a/transform_test.go b/transform_test.go index 0c5591d..71dd676 100644 --- a/transform_test.go +++ b/transform_test.go @@ -8,34 +8,34 @@ import ( ) func TestMap(t *testing.T) { - s := _OfSlice([]int{1, 2, 3}) - n := _Collect(_Map(s, func(v int) float64 { return float64(v * 2) })) + s := OfSlice([]int{1, 2, 3}) + n := Collect(Map(s, func(v int) float64 { return float64(v * 2) })) if [3]float64(n) != [...]float64{2, 4, 6} { t.Fatal(n) } } func TestFilter(t *testing.T) { - s := _OfSlice([]int{1, 2, 3}) - n := _Collect(_Filter(s, func(v int) bool { return v%2 != 0 })) + s := OfSlice([]int{1, 2, 3}) + n := Collect(Filter(s, func(v int) bool { return v%2 != 0 })) if [2]int(n) != [...]int{1, 3} { t.Fatal(n) } } func TestSkip(t *testing.T) { - s := _Collect(_Skip(_Limit(_Generate( + s := Collect(Skip(Limit(Generate( 0, 1), 3), 2), ) - if !_Equal(_OfSlice(s), _Of(2)) { + if !Equal(OfSlice(s), Of(2)) { t.Fatal(s) } } func TestLimit(t *testing.T) { - s := _Collect(_Limit(_Generate( + s := Collect(Limit(Generate( 0, 2), 3), ) @@ -45,16 +45,16 @@ func TestLimit(t *testing.T) { } func TestConcat(t *testing.T) { - s := _Collect(_Concat(_OfSlice([]int{1, 2, 3}), _OfSlice([]int{3, 2, 5}))) + s := Collect(Concat(OfSlice([]int{1, 2, 3}), OfSlice([]int{3, 2, 5}))) if [6]int(s) != [...]int{1, 2, 3, 3, 2, 5} { t.Fatal(s) } } func TestZip(t *testing.T) { - s1 := _OfSlice([]int{1, 2, 3, 4, 5}) - s2 := _OfSlice([]int{2, 3, 4, 5, 6}) - seq := _Zip(s1, s2) + s1 := OfSlice([]int{1, 2, 3, 4, 5}) + s2 := OfSlice([]int{2, 3, 4, 5, 6}) + seq := Zip(s1, s2) seq(func(v Zipped[int, int]) bool { if v.V2-v.V1 != 1 { t.Fatalf("unexpected values: %+v", v) @@ -68,9 +68,9 @@ func BenchmarkZip(b *testing.B) { slice2 := []int{2, 3, 4, 5, 6} for i := 0; i < b.N; i++ { - s1 := _OfSlice(slice1) - s2 := _OfSlice(slice2) - seq := _Zip(s1, s2) + s1 := OfSlice(slice1) + s2 := OfSlice(slice2) + seq := Zip(s1, s2) seq(func(v Zipped[int, int]) bool { return true }) @@ -78,38 +78,38 @@ func BenchmarkZip(b *testing.B) { } func TestIsSorted(t *testing.T) { - if _IsSorted(_OfSlice([]int{1, 2, 3, 2})) { + if IsSorted(OfSlice([]int{1, 2, 3, 2})) { t.Fatal("is not sorted") } - if !_IsSorted(_OfSlice([]int{1, 2, 3, 4, 5})) { + if !IsSorted(OfSlice([]int{1, 2, 3, 4, 5})) { t.Fatal("is sorted") } - if !_IsSorted(_OfSlice([]int{48, 48})) { + if !IsSorted(OfSlice([]int{48, 48})) { t.Fatal("is sorted") } } func TestMerge(t *testing.T) { - s1 := _OfSlice([]int{2, 3, 5}) - s2 := _OfSlice([]int{1, 2, 3, 4, 5}) - r := _Collect(_Merge(s1, s2)) + s1 := OfSlice([]int{2, 3, 5}) + s2 := OfSlice([]int{1, 2, 3, 4, 5}) + r := Collect(Merge(s1, s2)) if [8]int(r) != [...]int{1, 2, 2, 3, 3, 4, 5, 5} { t.Fatal(r) } } -func splitmerge[T cmp.Ordered](s []T) _Seq[T] { +func splitmerge[T cmp.Ordered](s []T) Seq[T] { if len(s) <= 1 { - return _OfSlice(s) + return OfSlice(s) } left := splitmerge(s[:len(s)/2]) right := splitmerge(s[len(s)/2:]) - return _Merge(left, right) + return Merge(left, right) } func mergesort[T cmp.Ordered](s []T) { - _AppendTo(splitmerge(s), s[:0]) + AppendTo(splitmerge(s), s[:0]) } func TestMergeSort(t *testing.T) { @@ -127,14 +127,14 @@ func FuzzMergeSort(f *testing.F) { slices.Sort(check) mergesort(s) - if !_Equal(_OfSlice(s), _OfSlice(check)) { + if !Equal(OfSlice(s), OfSlice(check)) { t.Fatal(s) } }) } func TestChunks(t *testing.T) { - s := _Collect(_Map(_Chunks(_OfSlice([]int{1, 2, 3, 4, 5}), + s := Collect(Map(Chunks(OfSlice([]int{1, 2, 3, 4, 5}), 2), slices.Clone), ) @@ -144,7 +144,7 @@ func TestChunks(t *testing.T) { } func TestSplit2(t *testing.T) { - s1, s2 := _CollectSplit(_Split2(_FromPair(_OfSlice([]Pair[int32, int64]{{1, 2}, {3, 4}, {5, 6}})))) + s1, s2 := CollectSplit(Split2(FromPair(OfSlice([]Pair[int32, int64]{{1, 2}, {3, 4}, {5, 6}})))) if !slices.Equal(s1, []int32{1, 3, 5}) { t.Fatal(s1) } @@ -160,24 +160,24 @@ func TestCache(t *testing.T) { i++ return } - seq := _Cache(f) - if s := _Collect(seq); !slices.Equal(s, []int{0}) { + seq := Cache(f) + if s := Collect(seq); !slices.Equal(s, []int{0}) { t.Fatal(s) } - if s := _Collect(seq); !slices.Equal(s, []int{0}) { + if s := Collect(seq); !slices.Equal(s, []int{0}) { t.Fatal(s) } } func TestEnumerate(t *testing.T) { - s := _Collect(_ToPair(_Enumerate(_Limit(_Generate(0, 2), 3)))) + s := Collect(ToPair(Enumerate(Limit(Generate(0, 2), 3)))) if !slices.Equal(s, []Pair[int, int]{{0, 0}, {1, 2}, {2, 4}}) { t.Fatal(s) } } func TestOr(t *testing.T) { - s := _Collect(_Or(_Of[int](), nil, _Of(1, 2, 3), _Of(4, 5, 6))) + s := Collect(Or(Of[int](), nil, Of(1, 2, 3), Of(4, 5, 6))) if !slices.Equal(s, []int{1, 2, 3}) { t.Fatal(s) }