golang.org/x/tools/gopls@v0.15.3/internal/util/slices/slices.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package slices 6 7 // Clone returns a copy of the slice. 8 // The elements are copied using assignment, so this is a shallow clone. 9 // TODO(rfindley): use go1.19 slices.Clone. 10 func Clone[S ~[]E, E any](s S) S { 11 // The s[:0:0] preserves nil in case it matters. 12 return append(s[:0:0], s...) 13 } 14 15 // Contains reports whether x is present in slice. 16 // TODO(adonovan): use go1.19 slices.Contains. 17 func Contains[S ~[]E, E comparable](slice S, x E) bool { 18 for _, elem := range slice { 19 if elem == x { 20 return true 21 } 22 } 23 return false 24 } 25 26 // IndexFunc returns the first index i satisfying f(s[i]), 27 // or -1 if none do. 28 // TODO(adonovan): use go1.19 slices.IndexFunc. 29 func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int { 30 for i := range s { 31 if f(s[i]) { 32 return i 33 } 34 } 35 return -1 36 } 37 38 // ContainsFunc reports whether at least one 39 // element e of s satisfies f(e). 40 // TODO(adonovan): use go1.19 slices.ContainsFunc. 41 func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool { 42 return IndexFunc(s, f) >= 0 43 } 44 45 // Concat returns a new slice concatenating the passed in slices. 46 // TODO(rfindley): use go1.22 slices.Concat. 47 func Concat[S ~[]E, E any](slices ...S) S { 48 size := 0 49 for _, s := range slices { 50 size += len(s) 51 if size < 0 { 52 panic("len out of range") 53 } 54 } 55 newslice := Grow[S](nil, size) 56 for _, s := range slices { 57 newslice = append(newslice, s...) 58 } 59 return newslice 60 } 61 62 // Grow increases the slice's capacity, if necessary, to guarantee space for 63 // another n elements. After Grow(n), at least n elements can be appended 64 // to the slice without another allocation. If n is negative or too large to 65 // allocate the memory, Grow panics. 66 // TODO(rfindley): use go1.19 slices.Grow. 67 func Grow[S ~[]E, E any](s S, n int) S { 68 if n < 0 { 69 panic("cannot be negative") 70 } 71 if n -= cap(s) - len(s); n > 0 { 72 s = append(s[:cap(s)], make([]E, n)...)[:len(s)] 73 } 74 return s 75 } 76 77 // Remove removes all values equal to elem from slice. 78 // 79 // The closest equivalent in the standard slices package is: 80 // 81 // DeleteFunc(func(x T) bool { return x == elem }) 82 func Remove[T comparable](slice []T, elem T) []T { 83 out := slice[:0] 84 for _, v := range slice { 85 if v != elem { 86 out = append(out, v) 87 } 88 } 89 return out 90 }