// Insert panics if i is out of range.
// This function is O(len(s) + len(v)).
func Insert[S ~[]E, E any](s S, i int, v ...E) S {
+ n := len(s)
m := len(v)
if m == 0 {
+ // Panic if i is not in the range [0:n] inclusive.
+ // See issue 63913.
+ _ = s[:n:n][i:]
return s
}
- n := len(s)
if i == n {
return append(s, v...)
}
}
// 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 panics if j > len(s) or s[i:j] is not a valid slice of s.
// 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
// zeroing those elements so that objects they reference can be garbage
// collected.
func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
+ i := IndexFunc(s, del)
+ if i == -1 {
+ return s
+ }
// Don't start copying elements until we find one to delete.
- for i, v := range s {
- if del(v) {
- j := i
- for i++; i < len(s); i++ {
- v = s[i]
- if !del(v) {
- s[j] = v
- j++
- }
- }
- return s[:j]
+ for j := i + 1; j < len(s); j++ {
+ if v := s[j]; !del(v) {
+ s[i] = v
+ i++
}
}
- return s
+ return s[:i]
}
// 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.
+// modified slice.
+// Replace panics if j > len(s) or 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
+ _ = s[i:j] // bounds check
if i == j {
return Insert(s, i, v...)
if i+len(v) <= j {
// Easy, as v fits in the deleted portion.
copy(r[i:], v)
- if i+len(v) != j {
- copy(r[i+len(v):], s[j:])
- }
+ copy(r[i+len(v):], s[j:])
return r
}
// 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 {
- // Preserve nil in case it matters.
- if s == nil {
- return nil
- }
- return append(S([]E{}), s...)
+ // The s[:0:0] preserves nil in case it matters.
+ return append(s[:0:0], s...)
}
// Compact replaces consecutive runs of equal elements with a single copy.
s[i], s[j] = s[j], s[i]
}
}
+
+// Concat returns a new slice concatenating the passed in slices.
+func Concat[S ~[]E, E any](slices ...S) S {
+ size := 0
+ for _, s := range slices {
+ size += len(s)
+ if size < 0 {
+ panic("len out of range")
+ }
+ }
+ newslice := Grow[S](nil, size)
+ for _, s := range slices {
+ newslice = append(newslice, s...)
+ }
+ return newslice
+}