func Grow[S constraints.Slice[T], T any](s S, n int) S {
	ss := make([]T, len(s), len(s)+n)
	copy(ss, s[:])
	return ss
}
Grow grows 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. If n is negative or too large to
allocate the memory, Grow will panic.
package slices
import "golang.design/x/go2generics/std/constraints"  
func Equal[T comparable](s1, s2 []T) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i := range s1 {
		if s1[i] != s2[i] {
			return false
		}
	}
	return true
}
func EqualFunc[T1, T2 any](s1 []T1, s2 []T2, eq func(T1, T2) bool) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i := range s1 {
		if !eq(s1[i], s2[i]) {
			return false
		}
	}
	return true
}
func Compare[T constraints.Ordered](s1, s2 []T) int {
	min := func(a, b int) int {
		if a < b {
			return a
		}
		return b
	}
	l := min(len(s1), len(s2))
	for i := 0; i < l; i++ {
		switch {
		case s1[i] == s2[i]:
			continue
		case s1[i] < s2[i]:
			return -1
		case s1[i] > s2[i]:
			return 1
		}
	}
	switch {
	case l == len(s1) && l == len(s2):
		return 0
	case l < len(s1):  
		return 1
	case l < len(s2):  
		fallthrough
	default:
		return -1
	}
}
func CompareFunc[T any](s1, s2 []T, cmp func(T, T) int) int {
	min := func(a, b int) int {
		if a < b {
			return a
		}
		return b
	}
	l := min(len(s1), len(s2))
	for i := 0; i < l; i++ {
		switch cmp(s1[i], s2[i]) {
		case 0:
			continue
		case -1:
			return -1
		case 1:
			return 1
		}
	}
	switch {
	case l == len(s1) && l == len(s2):
		return 0
	case l < len(s1):  
		return 1
	case l < len(s2):  
		fallthrough
	default:
		return -1
	}
}
func Index[T comparable](s []T, v T) int {
	for i := range s {
		if v == s[i] {
			return i
		}
	}
	return -1
}
func IndexFunc[T any](s []T, f func(T) bool) int {
	for i := range s {
		if f(s[i]) {
			return i
		}
	}
	return -1
}
func Contains[T comparable](s []T, v T) bool {
	return Index[T](s, v) != -1
}
func Insert[S constraints.Slice[T], T any](s S, i int, v ...T) S {
	if i > len(s) {
		panic("slices: out of slice index")
	}
	s = s[:i]
	s = append(s, v...)
	return s
}
func Delete[S constraints.Slice[T], T any](s S, i, j int) S {
	if !(0 < i && i < len(s)) || !(0 < j && j < len(s)) || i > j {
		panic("slices: invalid index i or j")
	}
	s = s[:i]
	s = append(s, s[j:]...)
	return s
}
func Clone[S constraints.Slice[T], T any](s S) S {
	ss := make([]T, len(s))
	for i := range s {
		ss[i] = s[i]
	}
	return ss
}
func Compact[S constraints.Slice[T], T comparable](s S) S {
	if s == nil {
		return s
	}
	lastIdx := len(s) - 1
	for i := len(s) - 2; i != 0; i-- {
		if s[i] == s[lastIdx] {
			continue
		}
		s = append(s[:i+1], s[lastIdx:]...)
		lastIdx = i
	}
	return s
}
func CompactFunc[S constraints.Slice[T], T any](s S, cmp func(T, T) bool) S {
	if s == nil {
		return s
	}
	lastIdx := len(s) - 1
	for i := len(s) - 2; i != 0; i-- {
		if cmp(s[i], s[lastIdx]) {
			continue
		}
		s = append(s[:i+1], s[lastIdx:]...)
		lastIdx = i
	}
	return s
}