From 862fa6d099fb046e90efd537b2c0ac2667c23d90 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 21 Jul 2023 12:50:48 -0700 Subject: [PATCH] sort: add gen_sort_variants support for x/exp/slices Also add a go:generate command to the standard library slices package. For #61374 Change-Id: I7aae8e451b7c6c4390e0344257478d1a96a14189 Reviewed-on: https://go-review.googlesource.com/c/go/+/511660 Run-TryBot: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gopher Robot Reviewed-by: Eli Bendersky Reviewed-by: Ian Lance Taylor --- src/slices/sort.go | 2 + src/sort/gen_sort_variants.go | 153 +++++++++++++++++++++++----------- 2 files changed, 106 insertions(+), 49 deletions(-) diff --git a/src/slices/sort.go b/src/slices/sort.go index 822f2fceb4..d5e998ce1e 100644 --- a/src/slices/sort.go +++ b/src/slices/sort.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:generate go run $GOROOT/src/sort/gen_sort_variants.go -generic + package slices import ( diff --git a/src/sort/gen_sort_variants.go b/src/sort/gen_sort_variants.go index 2c12b98db3..89500e1c10 100644 --- a/src/sort/gen_sort_variants.go +++ b/src/sort/gen_sort_variants.go @@ -68,51 +68,9 @@ type Variant struct { Funcs template.FuncMap } -func main() { - genGeneric := flag.Bool("generic", false, "generate generic versions") - flag.Parse() - - if *genGeneric { - generate(&Variant{ - Name: "generic_ordered", - Path: "zsortordered.go", - Package: "slices", - Imports: "import \"cmp\"\n", - FuncSuffix: "Ordered", - TypeParam: "[E cmp.Ordered]", - ExtraParam: "", - ExtraArg: "", - DataType: "[]E", - Funcs: template.FuncMap{ - "Less": func(name, i, j string) string { - return fmt.Sprintf("cmp.Less(%s[%s], %s[%s])", name, i, name, j) - }, - "Swap": func(name, i, j string) string { - return fmt.Sprintf("%s[%s], %s[%s] = %s[%s], %s[%s]", name, i, name, j, name, j, name, i) - }, - }, - }) - - generate(&Variant{ - Name: "generic_func", - Path: "zsortanyfunc.go", - Package: "slices", - FuncSuffix: "CmpFunc", - TypeParam: "[E any]", - ExtraParam: ", cmp func(a, b E) int", - ExtraArg: ", cmp", - DataType: "[]E", - Funcs: template.FuncMap{ - "Less": func(name, i, j string) string { - return fmt.Sprintf("(cmp(%s[%s], %s[%s]) < 0)", name, i, name, j) - }, - "Swap": func(name, i, j string) string { - return fmt.Sprintf("%s[%s], %s[%s] = %s[%s], %s[%s]", name, i, name, j, name, j, name, i) - }, - }, - }) - } else { - generate(&Variant{ +var ( + traditionalVariants = []Variant{ + Variant{ Name: "interface", Path: "zsortinterface.go", Package: "sort", @@ -130,9 +88,8 @@ func main() { return fmt.Sprintf("%s.Swap(%s, %s)", name, i, j) }, }, - }) - - generate(&Variant{ + }, + Variant{ Name: "func", Path: "zsortfunc.go", Package: "sort", @@ -150,7 +107,105 @@ func main() { return fmt.Sprintf("%s.Swap(%s, %s)", name, i, j) }, }, - }) + }, + } + + genericVariants = []Variant{ + Variant{ + Name: "generic_ordered", + Path: "zsortordered.go", + Package: "slices", + Imports: "import \"cmp\"\n", + FuncSuffix: "Ordered", + TypeParam: "[E cmp.Ordered]", + ExtraParam: "", + ExtraArg: "", + DataType: "[]E", + Funcs: template.FuncMap{ + "Less": func(name, i, j string) string { + return fmt.Sprintf("cmp.Less(%s[%s], %s[%s])", name, i, name, j) + }, + "Swap": func(name, i, j string) string { + return fmt.Sprintf("%s[%s], %s[%s] = %s[%s], %s[%s]", name, i, name, j, name, j, name, i) + }, + }, + }, + Variant{ + Name: "generic_func", + Path: "zsortanyfunc.go", + Package: "slices", + FuncSuffix: "CmpFunc", + TypeParam: "[E any]", + ExtraParam: ", cmp func(a, b E) int", + ExtraArg: ", cmp", + DataType: "[]E", + Funcs: template.FuncMap{ + "Less": func(name, i, j string) string { + return fmt.Sprintf("(cmp(%s[%s], %s[%s]) < 0)", name, i, name, j) + }, + "Swap": func(name, i, j string) string { + return fmt.Sprintf("%s[%s], %s[%s] = %s[%s], %s[%s]", name, i, name, j, name, j, name, i) + }, + }, + }, + } + + expVariants = []Variant{ + Variant{ + Name: "exp_ordered", + Path: "zsortordered.go", + Package: "slices", + Imports: "import \"golang.org/x/exp/constraints\"\n", + FuncSuffix: "Ordered", + TypeParam: "[E constraints.Ordered]", + ExtraParam: "", + ExtraArg: "", + DataType: "[]E", + Funcs: template.FuncMap{ + "Less": func(name, i, j string) string { + return fmt.Sprintf("cmpLess(%s[%s], %s[%s])", name, i, name, j) + }, + "Swap": func(name, i, j string) string { + return fmt.Sprintf("%s[%s], %s[%s] = %s[%s], %s[%s]", name, i, name, j, name, j, name, i) + }, + }, + }, + Variant{ + Name: "exp_func", + Path: "zsortanyfunc.go", + Package: "slices", + FuncSuffix: "CmpFunc", + TypeParam: "[E any]", + ExtraParam: ", cmp func(a, b E) int", + ExtraArg: ", cmp", + DataType: "[]E", + Funcs: template.FuncMap{ + "Less": func(name, i, j string) string { + return fmt.Sprintf("(cmp(%s[%s], %s[%s]) < 0)", name, i, name, j) + }, + "Swap": func(name, i, j string) string { + return fmt.Sprintf("%s[%s], %s[%s] = %s[%s], %s[%s]", name, i, name, j, name, j, name, i) + }, + }, + }, + } +) + +func main() { + genGeneric := flag.Bool("generic", false, "generate generic versions") + genExp := flag.Bool("exp", false, "generate x/exp/slices versions") + flag.Parse() + + var variants []Variant + if *genExp { + variants = expVariants + } else if *genGeneric { + variants = genericVariants + } else { + variants = traditionalVariants + } + for i := range variants { + generate(&variants[i]) } }