diff options
Diffstat (limited to 'vendor/golang.org/x/exp')
| -rw-r--r-- | vendor/golang.org/x/exp/AUTHORS | 3 | ||||
| -rw-r--r-- | vendor/golang.org/x/exp/CONTRIBUTORS | 3 | ||||
| -rw-r--r-- | vendor/golang.org/x/exp/slices/slices.go | 80 | ||||
| -rw-r--r-- | vendor/golang.org/x/exp/slices/sort.go | 61 | 
4 files changed, 91 insertions, 56 deletions
diff --git a/vendor/golang.org/x/exp/AUTHORS b/vendor/golang.org/x/exp/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/golang.org/x/exp/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/exp/CONTRIBUTORS b/vendor/golang.org/x/exp/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/golang.org/x/exp/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/exp/slices/slices.go b/vendor/golang.org/x/exp/slices/slices.go index 8a237c5d6..2540bd682 100644 --- a/vendor/golang.org/x/exp/slices/slices.go +++ b/vendor/golang.org/x/exp/slices/slices.go @@ -104,8 +104,8 @@ 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 { -	for i, vs := range s { -		if v == vs { +	for i := range s { +		if v == s[i] {  			return i  		}  	} @@ -115,8 +115,8 @@ 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 { -	for i, v := range s { -		if f(v) { +	for i := range s { +		if f(s[i]) {  			return i  		}  	} @@ -128,6 +128,12 @@ func Contains[E comparable](s []E, v E) bool {  	return Index(s, v) >= 0  } +// ContainsFunc reports whether at least one +// element e of s satisfies f(e). +func ContainsFunc[E any](s []E, f func(E) bool) bool { +	return IndexFunc(s, f) >= 0 +} +  // Insert inserts the values v... into s at index i,  // returning the modified slice.  // In the returned slice r, r[i] == v[0]. @@ -151,12 +157,35 @@ func Insert[S ~[]E, E any](s S, i int, v ...E) S {  // Delete removes the elements s[i:j] from s, returning the modified slice.  // Delete panics if s[i:j] is not a valid slice of s.  // Delete modifies the contents of the slice s; it does not create a new slice. -// Delete is O(len(s)-(j-i)), so if many items must be deleted, it is better to +// Delete is O(len(s)-j), so if many items must be deleted, it is better to  // make a single call deleting them all together than to delete one at a time. +// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those +// elements contain pointers you might consider zeroing those elements so that +// objects they reference can be garbage collected.  func Delete[S ~[]E, E any](s S, i, j int) S { +	_ = s[i:j] // bounds check +  	return append(s[:i], s[j:]...)  } +// Replace replaces the elements s[i:j] by the given v, and returns the +// modified slice. Replace panics if s[i:j] is not a valid slice of s. +func Replace[S ~[]E, E any](s S, i, j int, v ...E) S { +	_ = s[i:j] // verify that i:j is a valid subslice +	tot := len(s[:i]) + len(v) + len(s[j:]) +	if tot <= cap(s) { +		s2 := s[:tot] +		copy(s2[i+len(v):], s[j:]) +		copy(s2[i:], v) +		return s2 +	} +	s2 := make(S, tot) +	copy(s2, s[:i]) +	copy(s2[i:], v) +	copy(s2[i+len(v):], s[j:]) +	return s2 +} +  // Clone returns a copy of the slice.  // The elements are copied using assignment, so this is a shallow clone.  func Clone[S ~[]E, E any](s S) S { @@ -170,17 +199,20 @@ func Clone[S ~[]E, E any](s S) S {  // Compact replaces consecutive runs of equal elements with a single copy.  // This is like the uniq command found on Unix.  // Compact modifies the contents of the slice s; it does not create a new slice. +// When Compact discards m elements in total, it might not modify the elements +// s[len(s)-m:len(s)]. If those elements contain pointers you might consider +// zeroing those elements so that objects they reference can be garbage collected.  func Compact[S ~[]E, E comparable](s S) S { -	if len(s) == 0 { +	if len(s) < 2 {  		return s  	}  	i := 1 -	last := s[0] -	for _, v := range s[1:] { -		if v != last { -			s[i] = v +	for k := 1; k < len(s); k++ { +		if s[k] != s[k-1] { +			if i != k { +				s[i] = s[k] +			}  			i++ -			last = v  		}  	}  	return s[:i] @@ -188,16 +220,16 @@ func Compact[S ~[]E, E comparable](s S) S {  // CompactFunc is like Compact but uses a comparison function.  func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S { -	if len(s) == 0 { +	if len(s) < 2 {  		return s  	}  	i := 1 -	last := s[0] -	for _, v := range s[1:] { -		if !eq(v, last) { -			s[i] = v +	for k := 1; k < len(s); k++ { +		if !eq(s[k], s[k-1]) { +			if i != k { +				s[i] = s[k] +			}  			i++ -			last = v  		}  	}  	return s[:i] @@ -205,11 +237,19 @@ func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {  // Grow increases the slice's capacity, if necessary, to guarantee space for  // another n elements. After Grow(n), at least n elements can be appended -// to the slice without another allocation. Grow may modify elements of the -// slice between the length and the capacity. If n is negative or too large to +// to the slice without another allocation. If n is negative or too large to  // allocate the memory, Grow panics.  func Grow[S ~[]E, E any](s S, n int) S { -	return append(s, make(S, n)...)[:len(s)] +	if n < 0 { +		panic("cannot be negative") +	} +	if n -= cap(s) - len(s); n > 0 { +		// TODO(https://go.dev/issue/53888): Make using []E instead of S +		// to workaround a compiler bug where the runtime.growslice optimization +		// does not take effect. Revert when the compiler is fixed. +		s = append([]E(s)[:cap(s)], make([]E, n)...)[:len(s)] +	} +	return s  }  // Clip removes unused capacity from the slice, returning s[:len(s):len(s)]. diff --git a/vendor/golang.org/x/exp/slices/sort.go b/vendor/golang.org/x/exp/slices/sort.go index c22e74bd1..231b6448a 100644 --- a/vendor/golang.org/x/exp/slices/sort.go +++ b/vendor/golang.org/x/exp/slices/sort.go @@ -30,7 +30,7 @@ func SortFunc[E any](x []E, less func(a, b E) bool) {  	pdqsortLessFunc(x, 0, n, bits.Len(uint(n)), less)  } -// SortStable sorts the slice x while keeping the original order of equal +// SortStableFunc sorts the slice x while keeping the original order of equal  // elements, using less to compare elements.  func SortStableFunc[E any](x []E, less func(a, b E) bool) {  	stableLessFunc(x, len(x), less) @@ -62,46 +62,47 @@ func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool {  // sort order; it also returns a bool saying whether the target is really found  // in the slice. The slice must be sorted in increasing order.  func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool) { -	// search returns the leftmost position where f returns true, or len(x) if f -	// returns false for all x. This is the insertion position for target in x, -	// and could point to an element that's either == target or not. -	pos := search(len(x), func(i int) bool { return x[i] >= target }) -	if pos >= len(x) || x[pos] != target { -		return pos, false -	} else { -		return pos, true +	// Inlining is faster than calling BinarySearchFunc with a lambda. +	n := len(x) +	// Define x[-1] < target and x[n] >= target. +	// Invariant: x[i-1] < target, x[j] >= target. +	i, j := 0, n +	for i < j { +		h := int(uint(i+j) >> 1) // avoid overflow when computing h +		// i ≤ h < j +		if x[h] < target { +			i = h + 1 // preserves x[i-1] < target +		} else { +			j = h // preserves x[j] >= target +		}  	} +	// i == j, x[i-1] < target, and x[j] (= x[i]) >= target  =>  answer is i. +	return i, i < n && x[i] == target  }  // BinarySearchFunc works like BinarySearch, but uses a custom comparison -// function. The slice must be sorted in increasing order, where "increasing" is -// defined by cmp. cmp(a, b) is expected to return an integer comparing the two -// parameters: 0 if a == b, a negative number if a < b and a positive number if -// a > b. -func BinarySearchFunc[E any](x []E, target E, cmp func(E, E) int) (int, bool) { -	pos := search(len(x), func(i int) bool { return cmp(x[i], target) >= 0 }) -	if pos >= len(x) || cmp(x[pos], target) != 0 { -		return pos, false -	} else { -		return pos, true -	} -} - -func search(n int, f func(int) bool) int { -	// Define f(-1) == false and f(n) == true. -	// Invariant: f(i-1) == false, f(j) == true. +// function. The slice must be sorted in increasing order, where "increasing" +// is defined by cmp. cmp should return 0 if the slice element matches +// the target, a negative number if the slice element precedes the target, +// or a positive number if the slice element follows the target. +// cmp must implement the same ordering as the slice, such that if +// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice. +func BinarySearchFunc[E, T any](x []E, target T, cmp func(E, T) int) (int, bool) { +	n := len(x) +	// Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 . +	// Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0.  	i, j := 0, n  	for i < j {  		h := int(uint(i+j) >> 1) // avoid overflow when computing h  		// i ≤ h < j -		if !f(h) { -			i = h + 1 // preserves f(i-1) == false +		if cmp(x[h], target) < 0 { +			i = h + 1 // preserves cmp(x[i - 1], target) < 0  		} else { -			j = h // preserves f(j) == true +			j = h // preserves cmp(x[j], target) >= 0  		}  	} -	// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i. -	return i +	// i == j, cmp(x[i-1], target) < 0, and cmp(x[j], target) (= cmp(x[i], target)) >= 0  =>  answer is i. +	return i, i < n && cmp(x[i], target) == 0  }  type sortedHint int // hint for pdqsort when choosing the pivot  | 
