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  }