aboutsummaryrefslogtreecommitdiff
path: root/src/sort
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2019-04-30 15:23:14 -0400
committerBrad Fitzpatrick <bradfitz@golang.org>2019-05-02 20:30:31 +0000
commit0a338f75d4c64ba72cf586a28ec1a674c8b4bb77 (patch)
treefb096f1073d09a1a8c38aade73acb2b2e10170ba /src/sort
parentd2765de863355f8ae6e4354ae64c2099cd850382 (diff)
downloadgo-0a338f75d4c64ba72cf586a28ec1a674c8b4bb77.tar.xz
sort: simplify bootstrap
We compile package sort as part of the compiler bootstrap, to make sure the compiler uses a consistent sort algorithm no matter what version of Go it is compiled against. (This matters for elements that compare "equal" but are distinguishable.) Package sort was compiled in such a way as to disallow sort.Slice entirely during bootstrap (at least with some compilers), while cmd/internal/obj was compiled in such a way as to make obj.SortSlice available to all compilers, precisely because sort.Slice was not. This is all highly confusing. Simplify by making sort.Slice available all the time. Followup to CL 169137 and #30440 (and also CL 40114 and CL 73951). Change-Id: I127f4e02d6c71392805d256c3a90ef7c51f9ba0c Reviewed-on: https://go-review.googlesource.com/c/go/+/174525 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/sort')
-rw-r--r--src/sort/slice.go16
-rw-r--r--src/sort/slice_go113.go12
-rw-r--r--src/sort/slice_go14.go22
-rw-r--r--src/sort/slice_go18.go12
-rw-r--r--src/sort/slice_pre113.go46
5 files changed, 51 insertions, 57 deletions
diff --git a/src/sort/slice.go b/src/sort/slice.go
index 5196affcfd..1f42c2a3fd 100644
--- a/src/sort/slice.go
+++ b/src/sort/slice.go
@@ -2,14 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build !compiler_bootstrap go1.13
-
package sort
-import (
- "internal/reflectlite"
-)
-
// Slice sorts the provided slice given the provided less function.
//
// The sort is not guaranteed to be stable. For a stable sort, use
@@ -17,8 +11,8 @@ import (
//
// The function panics if the provided interface is not a slice.
func Slice(slice interface{}, less func(i, j int) bool) {
- rv := reflectlite.ValueOf(slice)
- swap := reflectlite.Swapper(slice)
+ rv := reflectValueOf(slice)
+ swap := reflectSwapper(slice)
length := rv.Len()
quickSort_func(lessSwap{less, swap}, 0, length, maxDepth(length))
}
@@ -28,8 +22,8 @@ func Slice(slice interface{}, less func(i, j int) bool) {
//
// The function panics if the provided interface is not a slice.
func SliceStable(slice interface{}, less func(i, j int) bool) {
- rv := reflectlite.ValueOf(slice)
- swap := reflectlite.Swapper(slice)
+ rv := reflectValueOf(slice)
+ swap := reflectSwapper(slice)
stable_func(lessSwap{less, swap}, rv.Len())
}
@@ -37,7 +31,7 @@ func SliceStable(slice interface{}, less func(i, j int) bool) {
//
// The function panics if the provided interface is not a slice.
func SliceIsSorted(slice interface{}, less func(i, j int) bool) bool {
- rv := reflectlite.ValueOf(slice)
+ rv := reflectValueOf(slice)
n := rv.Len()
for i := n - 1; i > 0; i-- {
if less(i, i-1) {
diff --git a/src/sort/slice_go113.go b/src/sort/slice_go113.go
new file mode 100644
index 0000000000..bf24db714a
--- /dev/null
+++ b/src/sort/slice_go113.go
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+// +build go1.13
+
+package sort
+
+import "internal/reflectlite"
+
+var reflectValueOf = reflectlite.ValueOf
+var reflectSwapper = reflectlite.Swapper
diff --git a/src/sort/slice_go14.go b/src/sort/slice_go14.go
new file mode 100644
index 0000000000..3bf5cbc00b
--- /dev/null
+++ b/src/sort/slice_go14.go
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+// +build !go1.8
+
+package sort
+
+import "reflect"
+
+var reflectValueOf = reflect.ValueOf
+
+func reflectSwapper(x interface{}) func(int, int) {
+ v := reflectValueOf(x)
+ tmp := reflect.New(v.Type().Elem()).Elem()
+ return func(i, j int) {
+ a, b := v.Index(i), v.Index(j)
+ tmp.Set(a)
+ a.Set(b)
+ b.Set(tmp)
+ }
+}
diff --git a/src/sort/slice_go18.go b/src/sort/slice_go18.go
new file mode 100644
index 0000000000..e1766040a7
--- /dev/null
+++ b/src/sort/slice_go18.go
@@ -0,0 +1,12 @@
+// Copyright 2017 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.
+
+// +build go1.8,!go1.13
+
+package sort
+
+import "reflect"
+
+var reflectValueOf = reflect.ValueOf
+var reflectSwapper = reflect.Swapper
diff --git a/src/sort/slice_pre113.go b/src/sort/slice_pre113.go
deleted file mode 100644
index 4d5f759a92..0000000000
--- a/src/sort/slice_pre113.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2017 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.
-
-// +build go1.8,!go1.13
-
-package sort
-
-import "reflect"
-
-// Slice sorts the provided slice given the provided less function.
-//
-// The sort is not guaranteed to be stable. For a stable sort, use
-// SliceStable.
-//
-// The function panics if the provided interface is not a slice.
-func Slice(slice interface{}, less func(i, j int) bool) {
- rv := reflect.ValueOf(slice)
- swap := reflect.Swapper(slice)
- length := rv.Len()
- quickSort_func(lessSwap{less, swap}, 0, length, maxDepth(length))
-}
-
-// SliceStable sorts the provided slice given the provided less
-// function while keeping the original order of equal elements.
-//
-// The function panics if the provided interface is not a slice.
-func SliceStable(slice interface{}, less func(i, j int) bool) {
- rv := reflect.ValueOf(slice)
- swap := reflect.Swapper(slice)
- stable_func(lessSwap{less, swap}, rv.Len())
-}
-
-// SliceIsSorted tests whether a slice is sorted.
-//
-// The function panics if the provided interface is not a slice.
-func SliceIsSorted(slice interface{}, less func(i, j int) bool) bool {
- rv := reflect.ValueOf(slice)
- n := rv.Len()
- for i := n - 1; i > 0; i-- {
- if less(i, i-1) {
- return false
- }
- }
- return true
-}