package main import ( "fmt" "log" "os" "os/exec" "path/filepath" "text/template" ) var stdtypes = []string{ "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64", "float32", "float64", //"complex64", //"complex128", "byte", "rune", "string", } type GenType struct { Gen bool N string Fields []string } type GenTypes []GenType var stdTmpl = template.Must(template.New("").Parse(`// Code generated by cmdgen DO NOT EDIT. package main import ( "container/heap" ) {{range .}} {{- if .Gen}} type {{.N}} struct{ oField int {{- range $i, $f := .Fields}} field{{$i}} {{$f}} {{- end}} } type HeapType{{.N}} []*{{.N}} {{- else}} type HeapType{{.N}} []{{.N}} {{- end}} func (h HeapType{{.N}}) Len() int { return len(h) } {{- if .Gen }} func (h HeapType{{.N}}) Less(i, j int) bool { return h[i].oField < h[j].oField } {{- else }} func (h HeapType{{.N}}) Less(i, j int) bool { return h[i] < h[j] } {{- end }} func (h HeapType{{.N}}) Swap(i, j int) { h[i], h[j] = h[j], h[i] } {{- if .Gen }} func (h *HeapType{{.N}}) Push(x any) { *h = append(*h, x.(*{{.N}})) } {{- else}} func (h *HeapType{{.N}}) Push(x any) { *h = append(*h, x.({{.N}})) } {{- end}} func (h *HeapType{{.N}}) Pop() any { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } {{end}} func main() { {{- range .}} heap{{.N}} := &HeapType{{.N}}{} heap.Init(heap{{.N}}) {{end -}} }`)) var genericTmpl = template.Must(template.New("").Parse(`// Code generated by cmdgen DO NOT EDIT. package main import ( "gheap" ) {{range .}} {{- if .Gen}} type {{.N}} struct{ oField int {{- range $i, $f := .Fields}} field{{$i}} {{$f}} {{- end}} } {{- end}} {{- end}} func main() { {{- range .}} {{- if .Gen}} slice{{.N}} := []*{{.N}}{} h{{.N}} := gheap.New(func(i, j *{{.N}}) bool { return i.oField < j.oField }, slice{{.N}}...) _ = h{{.N}}.Len() {{- else }} slice{{.N}} := []{{.N}}{} h{{.N}} := gheap.New(func(i, j {{.N}}) bool { return i < j }, slice{{.N}}...) _ = h{{.N}}.Len() {{- end }} {{end }} }`)) func gofmt(path string) { if err := exec.Command("gofmt", "-w", path).Run(); err != nil { log.Fatal(err) } } func main() { pwd, _ := os.Getwd() cmdPath := filepath.Join(pwd, `cmd`) os.RemoveAll(cmdPath) stdPath := filepath.Join(cmdPath, "heapstd") genericPath := filepath.Join(cmdPath, "heapgeneric") os.MkdirAll(stdPath, 0o755) os.MkdirAll(genericPath, 0o755) stdMainPath := filepath.Join(stdPath, "main.go") genericMainPath := filepath.Join(genericPath, "main.go") data := []GenType{} for _, st := range stdtypes { data = append(data, GenType{ Gen: false, N: st, }) } cFields := []string{} for _, st := range stdtypes { cFields = append(cFields, st) } data = append(data, GenType{ Gen: true, N: "compsite", Fields: cFields, }) for i := 0; i <= 100; i++ { data = append(data, GenType{ Gen: true, N: fmt.Sprintf("StructType%d", i), Fields: []string{ "string", }, }) } stdMain, _ := os.Create(filepath.Join(stdPath, "main.go")) if err := stdTmpl.Execute(stdMain, &data); err != nil { log.Fatal(err) } stdMain.Close() genericMain, _ := os.Create(filepath.Join(genericPath, "main.go")) if err := genericTmpl.Execute(genericMain, &data); err != nil { log.Fatal(err) } genericMain.Close() gofmt(stdMainPath) gofmt(genericMainPath) }