Skip to content

slices: relax the constraints to type whose underlying type is slice #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions slices/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import "constraints"
// Otherwise, the elements are compared in increasing index order, and the
// comparison stops at the first unequal pair.
// Floating point NaNs are not considered equal.
func Equal[E comparable](s1, s2 []E) bool {
func Equal[S ~[]E, E comparable](s1, s2 S) bool {
if len(s1) != len(s2) {
return false
}
Expand All @@ -31,7 +31,7 @@ func Equal[E comparable](s1, s2 []E) bool {
// EqualFunc returns false. Otherwise, the elements are compared in
// increasing index order, and the comparison stops at the first index
// for which eq returns false.
func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool {
func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
if len(s1) != len(s2) {
return false
}
Expand All @@ -52,7 +52,7 @@ func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool {
// considered less than the longer one.
// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
// Comparisons involving floating point NaNs are ignored.
func Compare[E constraints.Ordered](s1, s2 []E) int {
func Compare[S ~[]E, E constraints.Ordered](s1, s2 []E) int {
s2len := len(s2)
for i, v1 := range s1 {
if i >= s2len {
Expand All @@ -79,7 +79,7 @@ func Compare[E constraints.Ordered](s1, s2 []E) int {
// The result is the first non-zero result of cmp; if cmp always
// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
// and +1 if len(s1) > len(s2).
func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {
func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
s2len := len(s2)
for i, v1 := range s1 {
if i >= s2len {
Expand All @@ -98,7 +98,7 @@ func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int {

// Index returns the index of the first occurrence of v in s,
// or -1 if not present.
func Index[E comparable](s []E, v E) int {
func Index[S ~[]E, E comparable](s S, v E) int {
for i, vs := range s {
if v == vs {
return i
Expand All @@ -109,7 +109,7 @@ func Index[E comparable](s []E, v E) int {

// IndexFunc returns the first index i satisfying f(s[i]),
// or -1 if none do.
func IndexFunc[E any](s []E, f func(E) bool) int {
func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
for i, v := range s {
if f(v) {
return i
Expand All @@ -119,7 +119,7 @@ func IndexFunc[E any](s []E, f func(E) bool) int {
}

// Contains reports whether v is present in s.
func Contains[E comparable](s []E, v E) bool {
func Contains[S ~[]E, E comparable](s S, v E) bool {
return Index(s, v) >= 0
}

Expand Down
18 changes: 10 additions & 8 deletions slices/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,28 @@ package slices
import "constraints"

// Sort sorts a slice of any ordered type in ascending order.
func Sort[Elem constraints.Ordered](x []Elem) {
func Sort[S ~[]E, E constraints.Ordered](x S) {
n := len(x)
quickSortOrdered(x, 0, n, maxDepth(n))
// Due to golang/go#48619, constraints of quickSortOrdered and its related
// functsions are not changed. So cast S to []E for now.
quickSortOrdered([]E(x), 0, n, maxDepth(n))
}

// Sort sorts the slice x in ascending order as determined by the less function.
// This sort is not guaranteed to be stable.
func SortFunc[Elem any](x []Elem, less func(a, b Elem) bool) {
func SortFunc[S ~[]E, E any](x S, less func(a, b E) bool) {
n := len(x)
quickSortLessFunc(x, 0, n, maxDepth(n), less)
}

// SortStable sorts the slice x while keeping the original order of equal
// elements, using less to compare elements.
func SortStableFunc[Elem any](x []Elem, less func(a, b Elem) bool) {
func SortStableFunc[S ~[]E, E any](x S, less func(a, b E) bool) {
stableLessFunc(x, len(x), less)
}

// IsSorted reports whether x is sorted in ascending order.
func IsSorted[Elem constraints.Ordered](x []Elem) bool {
func IsSorted[S ~[]E, E constraints.Ordered](x S) bool {
for i := len(x) - 1; i > 0; i-- {
if x[i] < x[i-1] {
return false
Expand All @@ -37,7 +39,7 @@ func IsSorted[Elem constraints.Ordered](x []Elem) bool {

// IsSortedFunc reports whether x is sorted in ascending order, with less as the
// comparison function.
func IsSortedFunc[Elem any](x []Elem, less func(a, b Elem) bool) bool {
func IsSortedFunc[S ~[]E, E any](x S, less func(a, b E) bool) bool {
for i := len(x) - 1; i > 0; i-- {
if less(x[i], x[i-1]) {
return false
Expand All @@ -51,7 +53,7 @@ func IsSortedFunc[Elem any](x []Elem, less func(a, b Elem) bool) bool {
// which it could be inserted into the slice is returned; therefore, if the
// intention is to find target itself a separate check for equality with the
// element at the returned index is required.
func BinarySearch[Elem constraints.Ordered](x []Elem, target Elem) int {
func BinarySearch[S ~[]E, E constraints.Ordered](x S, target E) int {
return search(len(x), func(i int) bool { return x[i] >= target })
}

Expand All @@ -63,7 +65,7 @@ func BinarySearch[Elem constraints.Ordered](x []Elem, target Elem) int {
// the first true index. If there is no such index, BinarySearchFunc returns n.
// (Note that the "not found" return value is not -1 as in, for instance,
// strings.Index.) Search calls ok(i) only for i in the range [0, n).
func BinarySearchFunc[Elem any](x []Elem, ok func(Elem) bool) int {
func BinarySearchFunc[S ~[]E, E any](x S, ok func(E) bool) int {
return search(len(x), func(i int) bool { return ok(x[i]) })
}

Expand Down
20 changes: 10 additions & 10 deletions slices/zsortfunc.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions slices/zsortordered.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.