summaryrefslogtreecommitdiffstats
path: root/test/typeparam/ordered.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/typeparam/ordered.go')
-rw-r--r--test/typeparam/ordered.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/test/typeparam/ordered.go b/test/typeparam/ordered.go
new file mode 100644
index 0000000..d304298
--- /dev/null
+++ b/test/typeparam/ordered.go
@@ -0,0 +1,95 @@
+// run
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "math"
+ "sort"
+)
+
+type Ordered interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 |
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
+ ~float32 | ~float64 |
+ ~string
+}
+
+type orderedSlice[Elem Ordered] []Elem
+
+func (s orderedSlice[Elem]) Len() int { return len(s) }
+func (s orderedSlice[Elem]) Less(i, j int) bool {
+ if s[i] < s[j] {
+ return true
+ }
+ isNaN := func(f Elem) bool { return f != f }
+ if isNaN(s[i]) && !isNaN(s[j]) {
+ return true
+ }
+ return false
+}
+func (s orderedSlice[Elem]) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func _OrderedSlice[Elem Ordered](s []Elem) {
+ sort.Sort(orderedSlice[Elem](s))
+}
+
+var ints = []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
+var float64s = []float64{74.3, 59.0, math.Inf(1), 238.2, -784.0, 2.3, math.NaN(), math.NaN(), math.Inf(-1), 9845.768, -959.7485, 905, 7.8, 7.8}
+var strings = []string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}
+
+func TestSortOrderedInts() bool {
+ return testOrdered("ints", ints, sort.Ints)
+}
+
+func TestSortOrderedFloat64s() bool {
+ return testOrdered("float64s", float64s, sort.Float64s)
+}
+
+func TestSortOrderedStrings() bool {
+ return testOrdered("strings", strings, sort.Strings)
+}
+
+func testOrdered[Elem Ordered](name string, s []Elem, sorter func([]Elem)) bool {
+ s1 := make([]Elem, len(s))
+ copy(s1, s)
+ s2 := make([]Elem, len(s))
+ copy(s2, s)
+ _OrderedSlice(s1)
+ sorter(s2)
+ ok := true
+ if !sliceEq(s1, s2) {
+ fmt.Printf("%s: got %v, want %v", name, s1, s2)
+ ok = false
+ }
+ for i := len(s1) - 1; i > 0; i-- {
+ if s1[i] < s1[i-1] {
+ fmt.Printf("%s: element %d (%v) < element %d (%v)", name, i, s1[i], i-1, s1[i-1])
+ ok = false
+ }
+ }
+ return ok
+}
+
+func sliceEq[Elem Ordered](s1, s2 []Elem) bool {
+ for i, v1 := range s1 {
+ v2 := s2[i]
+ if v1 != v2 {
+ isNaN := func(f Elem) bool { return f != f }
+ if !isNaN(v1) || !isNaN(v2) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+func main() {
+ if !TestSortOrderedInts() || !TestSortOrderedFloat64s() || !TestSortOrderedStrings() {
+ panic("failure")
+ }
+}