github.com/mitranim/gg@v0.1.17/slice.go (about)

     1  package gg
     2  
     3  import (
     4  	"sort"
     5  )
     6  
     7  /*
     8  Syntactic shortcut for creating a slice out of the given values. Simply returns
     9  the slice of arguments as-is. Sometimes allows shorter code. Note that when
    10  calling this function with an existing slice, you get the EXACT same slice
    11  back, with no allocation. Also see `SliceOf` which returns `Slice[A]` rather
    12  than `[]A`.
    13  */
    14  func ToSlice[A any](val ...A) []A { return val }
    15  
    16  /*
    17  Syntactic shortcut for making `Slice[A]` out of the given values. Can also be
    18  used to perform a free type conversion from an existing slice, with no
    19  allocation. Also see `ToSlice` which returns `[]A` rather than `Slice[A]`.
    20  */
    21  func SliceOf[A any](val ...A) Slice[A] { return Slice[A](val) }
    22  
    23  /*
    24  Shortcut for converting an arbitrary number of slices to `Slice[Elem]`. When
    25  called with exactly one argument, this performs a free type conversion without
    26  an allocation. When called with 2 or more arguments, this concatenates the
    27  inputs, allocating a new slice.
    28  */
    29  func SliceFrom[Src ~[]Elem, Elem any](src ...Src) Slice[Elem] {
    30  	switch len(src) {
    31  	case 0:
    32  		return nil
    33  	case 1:
    34  		return Slice[Elem](src[0])
    35  	default:
    36  		return Slice[Elem](Concat(src...))
    37  	}
    38  }
    39  
    40  /*
    41  Typedef of an arbitrary slice with various methods that duplicate global slice
    42  functions such as `Get` or `Filter`. Useful as a shortcut for creating bound
    43  methods that can be passed to higher-order functions. Example:
    44  
    45  	values := []string{`one`, `two`, `three`}
    46  	indexes := []int{0, 2}
    47  	result := Map(indexes, SliceOf(values...).Get)
    48  	fmt.Println(grepr.String(result))
    49  	// []string{`one`, `three`}
    50  */
    51  type Slice[A any] []A
    52  
    53  // True if len <= 0. Inverse of `.IsNotEmpty`.
    54  func IsEmpty[Slice ~[]Elem, Elem any](val Slice) bool { return len(val) <= 0 }
    55  
    56  // Same as global `IsEmpty`.
    57  func (self Slice[_]) IsEmpty() bool { return IsEmpty(self) }
    58  
    59  // True if len > 0. Inverse of `.IsEmpty`.
    60  func IsNotEmpty[Slice ~[]Elem, Elem any](val Slice) bool { return len(val) > 0 }
    61  
    62  // Same as global `IsNotEmpty`.
    63  func (self Slice[_]) IsNotEmpty() bool { return IsNotEmpty(self) }
    64  
    65  // Same as `len(val)` but can be passed to higher-order functions.
    66  func Len[Slice ~[]Elem, Elem any](val Slice) int { return len(val) }
    67  
    68  // Same as global `Len`.
    69  func (self Slice[_]) Len() int { return len(self) }
    70  
    71  // Same as `len(PtrGet(val))` but can be passed to higher-order functions.
    72  func PtrLen[Slice ~[]Elem, Elem any](val *Slice) int { return len(PtrGet(val)) }
    73  
    74  // Same as global `PtrLen`.
    75  func (self *Slice[_]) PtrLen() int { return PtrLen(self) }
    76  
    77  // Same as `cap(val)` but can be passed to higher-order functions.
    78  func Cap[Slice ~[]Elem, Elem any](val Slice) int { return cap(val) }
    79  
    80  // Same as global `Cap`.
    81  func (self Slice[_]) Cap() int { return cap(self) }
    82  
    83  // Amount of unused capacity in the given slice.
    84  func CapUnused[Slice ~[]Elem, Elem any](src Slice) int { return cap(src) - len(src) }
    85  
    86  // Same as global `CapUnused`.
    87  func (self Slice[_]) CapUnused() int { return CapUnused(self) }
    88  
    89  /*
    90  Amount of missing capacity that needs to be allocated to append the given amount
    91  of additional elements.
    92  */
    93  func CapMissing[Slice ~[]Elem, Elem any](src Slice, size int) int {
    94  	return MaxPrim2(0, size-CapUnused(src))
    95  }
    96  
    97  // Same as global `CapMissing`.
    98  func (self Slice[_]) CapMissing(size int) int { return CapMissing(self, size) }
    99  
   100  // Counts the total length of the given slices.
   101  func Lens[Slice ~[]Elem, Elem any](val ...Slice) int { return Sum(val, Len[Slice]) }
   102  
   103  // Grows the length of the given slice by appending N zero values.
   104  func GrowLen[Slice ~[]Elem, Elem any](src Slice, size int) Slice {
   105  	return append(src, make(Slice, size)...)
   106  }
   107  
   108  // Same as global `GrowLen`.
   109  func (self Slice[A]) GrowLen(size int) Slice[A] { return GrowLen(self, size) }
   110  
   111  /*
   112  Missing feature of the language / standard library. Ensures at least this much
   113  unused capacity (not total capacity). If there is already enough capacity,
   114  returns the slice as-is. Otherwise allocates a new slice, doubling the capacity
   115  as many times as needed until it accommodates enough elements. Use this when
   116  further growth is expected. When further growth is not expected, use
   117  `GrowCapExact` instead. Similar to `(*bytes.Buffer).Grow` but works for all
   118  slice types and avoids any wrapping, unwrapping, or spurious escapes to the
   119  heap.
   120  */
   121  func GrowCap[Slice ~[]Elem, Elem any](src Slice, size int) Slice {
   122  	missing := CapMissing(src, size)
   123  	if !(missing > 0) {
   124  		return src
   125  	}
   126  
   127  	prev := MaxPrim2(0, cap(src))
   128  	next := Or(prev, 1)
   129  	for next < prev+size {
   130  		next *= 2
   131  	}
   132  
   133  	out := make(Slice, len(src), next)
   134  	copy(out, src)
   135  	return out
   136  }
   137  
   138  // Same as global `GrowCap`.
   139  func (self Slice[A]) GrowCap(size int) Slice[A] { return GrowCap(self, size) }
   140  
   141  /*
   142  Missing feature of the language / standard library. Ensures at least this much
   143  unused capacity (not total capacity). If there is already enough capacity,
   144  returns the slice as-is. Otherwise allocates a new slice with EXACTLY enough
   145  additional capacity. Use this when further growth is not expected. When further
   146  growth is expected, use `GrowCap` instead.
   147  */
   148  func GrowCapExact[Slice ~[]Elem, Elem any](src Slice, size int) Slice {
   149  	missing := CapMissing(src, size)
   150  	if !(missing > 0) {
   151  		return src
   152  	}
   153  
   154  	out := make(Slice, len(src), cap(src)+missing)
   155  	copy(out, src)
   156  	return out
   157  }
   158  
   159  // Same as global `GrowCapExact`.
   160  func (self Slice[A]) GrowCapExact(size int) Slice[A] { return GrowCapExact(self, size) }
   161  
   162  /*
   163  Returns a modified slice where length is reduced to the given size. Negative
   164  size is equivalent to zero. If the current length is already shorter, it's
   165  unaffected.
   166  */
   167  func TruncLen[Slice ~[]Elem, Elem any](src Slice, size int) Slice {
   168  	if size < len(src) {
   169  		if size < 0 {
   170  			return src[:0]
   171  		}
   172  		return src[:size]
   173  	}
   174  	return src
   175  }
   176  
   177  // Same as global `TruncLen`.
   178  func (self Slice[A]) TruncLen(size int) Slice[A] { return TruncLen(self, size) }
   179  
   180  // Zeroes each element of the given slice.
   181  func SliceZero[A any](val []A) {
   182  	var zero A
   183  	for ind := range val {
   184  		val[ind] = zero
   185  	}
   186  }
   187  
   188  // Same as global `SliceZero`.
   189  func (self Slice[_]) Zero() { SliceZero(self) }
   190  
   191  /*
   192  Collapses the slice's length, preserving the capacity. Does not modify any
   193  elements. If the pointer is nil, does nothing.
   194  */
   195  func Trunc[Slice ~[]Elem, Elem any](ptr *Slice) {
   196  	if ptr == nil {
   197  		return
   198  	}
   199  	tar := *ptr
   200  	if tar != nil {
   201  		*ptr = tar[:0]
   202  	}
   203  }
   204  
   205  // Same as global `Trunc`.
   206  func (self *Slice[_]) Trunc() { Trunc(self) }
   207  
   208  /*
   209  If the index is within bounds, returns the value at that index and true.
   210  Otherwise returns zero value and false.
   211  */
   212  func Got[A any](src []A, ind int) (A, bool) {
   213  	if ind >= 0 && ind < len(src) {
   214  		return src[ind], true
   215  	}
   216  	return Zero[A](), false
   217  }
   218  
   219  // Same as global `Got`.
   220  func (self Slice[A]) Got(ind int) (A, bool) { return Got(self, ind) }
   221  
   222  /*
   223  If the index is within bounds, returns the value at that index.
   224  Otherwise returns zero value.
   225  */
   226  func Get[A any](src []A, ind int) A {
   227  	if ind >= 0 && ind < len(src) {
   228  		return src[ind]
   229  	}
   230  	return Zero[A]()
   231  }
   232  
   233  // Same as global `Get`.
   234  func (self Slice[A]) Get(ind int) A { return Get(self, ind) }
   235  
   236  /*
   237  If the index is within bounds, returns a pointer to the value at that index.
   238  Otherwise returns nil.
   239  */
   240  func GetPtr[A any](src []A, ind int) *A {
   241  	if ind >= 0 && ind < len(src) {
   242  		return &src[ind]
   243  	}
   244  	return nil
   245  }
   246  
   247  // Same as global `GetPtr`.
   248  func (self Slice[A]) GetPtr(ind int) *A { return GetPtr(self, ind) }
   249  
   250  /*
   251  Sets a value at an index, same as by using the built-in square bracket syntax.
   252  Useful as a shortcut for inline bound functions.
   253  */
   254  func (self Slice[A]) Set(ind int, val A) { self[ind] = val }
   255  
   256  /*
   257  Returns a shallow copy of the given slice. The capacity of the resulting slice
   258  is equal to its length.
   259  */
   260  func Clone[Slice ~[]Elem, Elem any](src Slice) Slice {
   261  	if src == nil {
   262  		return nil
   263  	}
   264  
   265  	out := make(Slice, len(src))
   266  	copy(out, src)
   267  	return out
   268  }
   269  
   270  // Same as global `Clone`.
   271  func (self Slice[A]) Clone() Slice[A] { return Clone(self) }
   272  
   273  /*
   274  Same as `append`, but makes a copy instead of mutating the original.
   275  Useful when reusing one "base" slice for in multiple append calls.
   276  */
   277  func CloneAppend[Slice ~[]Elem, Elem any](src Slice, val ...Elem) Slice {
   278  	if src == nil && val == nil {
   279  		return nil
   280  	}
   281  
   282  	out := make(Slice, 0, len(src)+len(val))
   283  	out = append(out, src...)
   284  	out = append(out, val...)
   285  	return out
   286  }
   287  
   288  // Same as global `CloneAppend`.
   289  func (self Slice[A]) CloneAppend(val ...A) Slice[A] {
   290  	return CloneAppend(self, val...)
   291  }
   292  
   293  /*
   294  Appends the given elements to the given slice. Similar to built-in `append` but
   295  syntactically shorter.
   296  */
   297  func Append[Slice ~[]Elem, Elem any](ptr *Slice, val ...Elem) {
   298  	if ptr != nil {
   299  		*ptr = append(*ptr, val...)
   300  	}
   301  }
   302  
   303  // Same as global `Append`.
   304  func (self *Slice[A]) Append(val ...A) { Append(self, val...) }
   305  
   306  /*
   307  If the target pointer is nil, does nothing and returns -1. Otherwise appends the
   308  given element to the given slice (like `Append`) and returns the last index
   309  of the resulting slice. Also see `AppendPtr`.
   310  */
   311  func AppendIndex[Slice ~[]Elem, Elem any](ptr *Slice, val Elem) int {
   312  	if ptr == nil {
   313  		return -1
   314  	}
   315  
   316  	tar := *ptr
   317  	tar = append(tar, val)
   318  	*ptr = tar
   319  	return LastIndex(tar)
   320  }
   321  
   322  // Same as global `AppendIndex`.
   323  func (self *Slice[A]) AppendIndex(val A) int { return AppendIndex(self, val) }
   324  
   325  /*
   326  Appends the given element to the given slice, returning the pointer to the newly
   327  appended position in the slice. If the target pointer is nil, does nothing and
   328  returns nil. Also see `AppendIndex`.
   329  */
   330  func AppendPtr[Slice ~[]Elem, Elem any](ptr *Slice, val Elem) *Elem {
   331  	if ptr == nil {
   332  		return nil
   333  	}
   334  
   335  	tar := append(*ptr, val)
   336  	*ptr = tar
   337  	return LastPtr(tar)
   338  }
   339  
   340  // Same as global `AppendPtr`.
   341  func (self *Slice[A]) AppendPtr(val A) *A { return AppendPtr(self, val) }
   342  
   343  /*
   344  Appends a zero element to the given slice, returning the pointer to the newly
   345  appended position in the slice. If the target pointer is nil, does nothing and
   346  returns nil.
   347  */
   348  func AppendPtrZero[Slice ~[]Elem, Elem any](ptr *Slice) *Elem {
   349  	return AppendPtr(ptr, Zero[Elem]())
   350  }
   351  
   352  // Same as global `AppendPtrZero`.
   353  func (self *Slice[A]) AppendPtrZero() *A { return AppendPtrZero(self) }
   354  
   355  /*
   356  Returns the first element of the given slice. If the slice is empty, returns the
   357  zero value.
   358  */
   359  func Head[Slice ~[]Elem, Elem any](val Slice) Elem { return Get(val, 0) }
   360  
   361  // Same as global `Head`.
   362  func (self Slice[A]) Head() A { return Head(self) }
   363  
   364  /*
   365  Returns a pointer to the first element of the given slice. If the slice is
   366  empty, the pointer is nil.
   367  */
   368  func HeadPtr[Slice ~[]Elem, Elem any](val Slice) *Elem { return GetPtr(val, 0) }
   369  
   370  // Same as global `HeadPtr`.
   371  func (self Slice[A]) HeadPtr() *A { return HeadPtr(self) }
   372  
   373  func PopHead[Slice ~[]Elem, Elem any](ptr *Slice) Elem {
   374  	if ptr == nil {
   375  		return Zero[Elem]()
   376  	}
   377  
   378  	head, tail := Head(*ptr), Tail(*ptr)
   379  	*ptr = tail
   380  	return head
   381  }
   382  
   383  // Same as global `PopHead`.
   384  func (self *Slice[A]) PopHead() A { return PopHead(self) }
   385  
   386  /*
   387  Returns the last element of the given slice. If the slice is empty, returns the
   388  zero value.
   389  */
   390  func Last[Slice ~[]Elem, Elem any](val Slice) Elem { return Get(val, len(val)-1) }
   391  
   392  // Same as global `Last`.
   393  func (self Slice[A]) Last() A { return Last(self) }
   394  
   395  /*
   396  Returns a pointer to the last element of the given slice. If the slice is empty,
   397  the pointer is nil.
   398  */
   399  func LastPtr[Slice ~[]Elem, Elem any](val Slice) *Elem { return GetPtr(val, len(val)-1) }
   400  
   401  // Same as global `LastPtr`.
   402  func (self Slice[A]) LastPtr() *A { return LastPtr(self) }
   403  
   404  /*
   405  Returns the index of the last element of the given slice.
   406  Same as `len(val)-1`. If slice is empty, returns -1.
   407  */
   408  func LastIndex[Slice ~[]Elem, Elem any](val Slice) int { return len(val) - 1 }
   409  
   410  // Same as global `LastIndex`.
   411  func (self Slice[A]) LastIndex() int { return LastIndex(self) }
   412  
   413  func PopLast[Slice ~[]Elem, Elem any](ptr *Slice) Elem {
   414  	if ptr == nil {
   415  		return Zero[Elem]()
   416  	}
   417  
   418  	init, last := Init(*ptr), Last(*ptr)
   419  	*ptr = init
   420  	return last
   421  }
   422  
   423  // Same as global `PopLast`.
   424  func (self *Slice[A]) PopLast() A { return PopLast(self) }
   425  
   426  /*
   427  Returns the initial part of the given slice: all except the last value.
   428  If the slice is nil, returns nil.
   429  */
   430  func Init[Slice ~[]Elem, Elem any](val Slice) Slice {
   431  	if len(val) <= 0 {
   432  		return val
   433  	}
   434  	return val[:len(val)-1]
   435  }
   436  
   437  // Same as global `Init`.
   438  func (self Slice[A]) Init() Slice[A] { return Init(self) }
   439  
   440  /*
   441  Returns the tail part of the given slice: all except the first value.
   442  If the slice is nil, returns nil.
   443  */
   444  func Tail[Slice ~[]Elem, Elem any](val Slice) Slice {
   445  	if len(val) <= 0 {
   446  		return val
   447  	}
   448  	return val[1:]
   449  }
   450  
   451  // Same as global `Tail`.
   452  func (self Slice[A]) Tail() Slice[A] { return Tail(self) }
   453  
   454  // Returns a subslice containing N elements from the start.
   455  func Take[Slice ~[]Elem, Elem any](src Slice, size int) Slice {
   456  	return src[:MaxPrim2(0, MinPrim2(size, len(src)))]
   457  }
   458  
   459  // Same as global `Take`.
   460  func (self Slice[A]) Take(size int) Slice[A] { return Take(self, size) }
   461  
   462  // Returns a subslice excluding N elements from the start.
   463  func Drop[Slice ~[]Elem, Elem any](src Slice, size int) Slice {
   464  	return src[MaxPrim2(0, MinPrim2(size, len(src))):]
   465  }
   466  
   467  // Same as global `Drop`.
   468  func (self Slice[A]) Drop(size int) Slice[A] { return Drop(self, size) }
   469  
   470  /*
   471  Returns a subslice containing only elements at the start of the slice
   472  for which the given function contiguously returned `true`.
   473  */
   474  func TakeWhile[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) Slice {
   475  	return Take(src, 1+FindIndex(src, func(val Elem) bool { return !fun(val) }))
   476  }
   477  
   478  // Same as global `TakeWhile`.
   479  func (self Slice[A]) TakeWhile(fun func(A) bool) Slice[A] {
   480  	return TakeWhile(self, fun)
   481  }
   482  
   483  /*
   484  Returns a subslice excluding elements at the start of the slice
   485  for which the given function contiguously returned `true`.
   486  */
   487  func DropWhile[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) Slice {
   488  	return Drop(src, 1+FindIndex(src, fun))
   489  }
   490  
   491  // Same as global `DropWhile`.
   492  func (self Slice[A]) DropWhile(fun func(A) bool) Slice[A] {
   493  	return DropWhile(self, fun)
   494  }
   495  
   496  // Calls the given function for each element of the given slice.
   497  func Each[Slice ~[]Elem, Elem any](val Slice, fun func(Elem)) {
   498  	if fun != nil {
   499  		for _, val := range val {
   500  			fun(val)
   501  		}
   502  	}
   503  }
   504  
   505  // Same as global `Each`.
   506  func (self Slice[A]) Each(val Slice[A], fun func(A)) { Each(self, fun) }
   507  
   508  /*
   509  Calls the given function for each element's pointer in the given slice.
   510  The pointer is always non-nil.
   511  */
   512  func EachPtr[Slice ~[]Elem, Elem any](val Slice, fun func(*Elem)) {
   513  	if fun != nil {
   514  		for ind := range val {
   515  			fun(&val[ind])
   516  		}
   517  	}
   518  }
   519  
   520  // Same as global `EachPtr`.
   521  func (self Slice[A]) EachPtr(fun func(*A)) { EachPtr(self, fun) }
   522  
   523  /*
   524  Similar to `Each` but iterates two slices pairwise. If slice lengths don't
   525  match, panics.
   526  */
   527  func Each2[A, B any](one []A, two []B, fun func(A, B)) {
   528  	validateLenMatch(len(one), len(two))
   529  
   530  	if fun != nil {
   531  		for ind := range one {
   532  			fun(one[ind], two[ind])
   533  		}
   534  	}
   535  }
   536  
   537  /*
   538  Returns the smallest value from among the inputs, which must be comparable
   539  primitives. For non-primitives, see `Min`.
   540  */
   541  func MinPrim[A LesserPrim](val ...A) A { return Fold1(val, MinPrim2[A]) }
   542  
   543  /*
   544  Returns the largest value from among the inputs, which must be comparable
   545  primitives. For non-primitives, see `Max`.
   546  */
   547  func MaxPrim[A LesserPrim](val ...A) A { return Fold1(val, MaxPrim2[A]) }
   548  
   549  /*
   550  Returns the smallest value from among the inputs. For primitive types that don't
   551  implement `Lesser`, see `MinPrim`.
   552  */
   553  func Min[A Lesser[A]](val ...A) A { return Fold1(val, Min2[A]) }
   554  
   555  /*
   556  Returns the largest value from among the inputs. For primitive types that don't
   557  implement `Lesser`, see `MaxPrim`.
   558  */
   559  func Max[A Lesser[A]](val ...A) A { return Fold1(val, Max2[A]) }
   560  
   561  /*
   562  Calls the given function for each element of the given slice and returns the
   563  smallest value from among the results, which must be comparable primitives.
   564  For non-primitives, see `MinBy`.
   565  */
   566  func MinPrimBy[Src any, Out LesserPrim](src []Src, fun func(Src) Out) Out {
   567  	if len(src) <= 0 || fun == nil {
   568  		return Zero[Out]()
   569  	}
   570  
   571  	return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out {
   572  		return MinPrim2(acc, fun(src))
   573  	})
   574  }
   575  
   576  /*
   577  Calls the given function for each element of the given slice and returns the
   578  smallest value from among the results. For primitive types that don't implement
   579  `Lesser`, see `MinPrimBy`.
   580  */
   581  func MinBy[Src any, Out Lesser[Out]](src []Src, fun func(Src) Out) Out {
   582  	if len(src) <= 0 || fun == nil {
   583  		return Zero[Out]()
   584  	}
   585  
   586  	return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out {
   587  		return Min2(acc, fun(src))
   588  	})
   589  }
   590  
   591  /*
   592  Calls the given function for each element of the given slice and returns the
   593  largest value from among the results, which must be comparable primitives.
   594  For non-primitives, see `MaxBy`.
   595  */
   596  func MaxPrimBy[Src any, Out LesserPrim](src []Src, fun func(Src) Out) Out {
   597  	if len(src) <= 0 || fun == nil {
   598  		return Zero[Out]()
   599  	}
   600  
   601  	return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out {
   602  		return MaxPrim2(acc, fun(src))
   603  	})
   604  }
   605  
   606  /*
   607  Calls the given function for each element of the given slice and returns the
   608  largest value from among the results. For primitive types that don't implement
   609  `Lesser`, see `MaxPrimBy`.
   610  */
   611  func MaxBy[Src any, Out Lesser[Out]](src []Src, fun func(Src) Out) Out {
   612  	if len(src) <= 0 || fun == nil {
   613  		return Zero[Out]()
   614  	}
   615  
   616  	return Fold(src[1:], fun(src[0]), func(acc Out, src Src) Out {
   617  		return Max2(acc, fun(src))
   618  	})
   619  }
   620  
   621  /*
   622  Calls the given function on each element of the given slice and returns the sum
   623  of all results, combined via `+`.
   624  */
   625  func Sum[Src any, Out Plusable](src []Src, fun func(Src) Out) Out {
   626  	if fun == nil {
   627  		return Zero[Out]()
   628  	}
   629  	return Foldz(src, func(acc Out, src Src) Out { return acc + fun(src) })
   630  }
   631  
   632  /*
   633  Counts occurrences elements of the given slice, keyed by calling the given
   634  function for each element, and returning the resulting map. If the function is
   635  nil, returns nil. Compare `Group` which returns `map[Key][]Val` rather than
   636  `map[Key]int`, and `Index` which returns `map[Key]Val`.
   637  */
   638  func Counts[Slice ~[]Val, Key comparable, Val any](src Slice, fun func(Val) Key) map[Key]int {
   639  	if fun == nil {
   640  		return nil
   641  	}
   642  
   643  	out := map[Key]int{}
   644  	CountsInto(out, src, fun)
   645  	return out
   646  }
   647  
   648  /*
   649  Counts occurrences elements of the given slice, keyed by calling the given
   650  function for each element, modifying the given map, which must be non-nil if
   651  the slice is non-empty. If the function is nil, does nothing.
   652  */
   653  func CountsInto[Key comparable, Val any](tar map[Key]int, src []Val, fun func(Val) Key) {
   654  	if fun == nil {
   655  		return
   656  	}
   657  	for _, val := range src {
   658  		tar[fun(val)]++
   659  	}
   660  }
   661  
   662  /*
   663  Maps one slice to another. The resulting slice has exactly the same length as
   664  the original. Each element is created by calling the given function on the
   665  corresponding element of the original slice. The name refers to a well-known
   666  functional programming abstraction which doesn't have anything in common with
   667  the Go `map` types. Unlike many other higher-order slice functions, this one
   668  requires a non-nil function.
   669  */
   670  func Map[A, B any](src []A, fun func(A) B) []B {
   671  	if src == nil {
   672  		return nil
   673  	}
   674  
   675  	out := make([]B, 0, len(src))
   676  	for _, val := range src {
   677  		out = append(out, fun(val))
   678  	}
   679  	return out
   680  }
   681  
   682  /*
   683  Similar to `Map` but instead of creating a new slice, appends to an existing
   684  slice.
   685  */
   686  func MapAppend[
   687  	Src ~[]SrcVal,
   688  	Tar ~[]TarVal,
   689  	SrcVal any,
   690  	TarVal any,
   691  ](ptr *Tar, src Src, fun func(SrcVal) TarVal) {
   692  	if ptr == nil || fun == nil {
   693  		return
   694  	}
   695  
   696  	tar := GrowCap(*ptr, len(src))
   697  	for _, val := range src {
   698  		tar = append(tar, fun(val))
   699  	}
   700  	*ptr = tar
   701  }
   702  
   703  /*
   704  Similar to `Map`, but instead of creating a new slice, mutates the old one in
   705  place by calling the given function on each element.
   706  */
   707  func MapMut[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) Elem) Slice {
   708  	if fun != nil {
   709  		for ind := range src {
   710  			src[ind] = fun(src[ind])
   711  		}
   712  	}
   713  	return src
   714  }
   715  
   716  // Same as global `MapMut`.
   717  func (self Slice[A]) MapMut(fun func(A) A) Slice[A] { return MapMut(self, fun) }
   718  
   719  /*
   720  Similar to `Map`, but calls the given function on each element pointer, rather
   721  than on each element. Every pointer is non-nil.
   722  */
   723  func MapPtr[A, B any](src []A, fun func(*A) B) []B {
   724  	if src == nil {
   725  		return nil
   726  	}
   727  
   728  	out := make([]B, 0, len(src))
   729  	for ind := range src {
   730  		out = append(out, fun(&src[ind]))
   731  	}
   732  	return out
   733  }
   734  
   735  /*
   736  Similar to `Map` but iterates two slices pairwise, passing each element pair to
   737  the mapping function. If slice lengths don't match, panics.
   738  */
   739  func Map2[A, B, C any](one []A, two []B, fun func(A, B) C) []C {
   740  	validateLenMatch(len(one), len(two))
   741  
   742  	if one == nil || two == nil {
   743  		return nil
   744  	}
   745  
   746  	out := make([]C, 0, len(one))
   747  	for ind := range one {
   748  		out = append(out, fun(one[ind], two[ind]))
   749  	}
   750  	return out
   751  }
   752  
   753  // Similar to `Map` but excludes any zero values produced by the given function.
   754  func MapCompact[A, B any](src []A, fun func(A) B) []B {
   755  	if fun == nil {
   756  		return nil
   757  	}
   758  
   759  	var out []B
   760  	for _, val := range src {
   761  		val := fun(val)
   762  		if !IsZero(val) {
   763  			out = append(out, val)
   764  		}
   765  	}
   766  	return out
   767  }
   768  
   769  // Similar to `Map` but concats the slices returned by the given function.
   770  func MapFlat[Out ~[]B, A, B any](src []A, fun func(A) Out) Out {
   771  	if src == nil {
   772  		return nil
   773  	}
   774  
   775  	var out Out
   776  	for _, val := range src {
   777  		out = append(out, fun(val)...)
   778  	}
   779  	return out
   780  }
   781  
   782  // Similar to `Map` but excludes duplicates.
   783  func MapUniq[A any, B comparable](src []A, fun func(A) B) []B {
   784  	if src == nil {
   785  		return nil
   786  	}
   787  
   788  	switch len(src) {
   789  	case 0:
   790  		return []B{}
   791  
   792  	case 1:
   793  		return []B{fun(src[0])}
   794  
   795  	case 2:
   796  		one := fun(src[0])
   797  		two := fun(src[1])
   798  		if one == two {
   799  			return []B{one}
   800  		}
   801  		return []B{one, two}
   802  
   803  	default:
   804  		set := make(Set[B])
   805  		out := make([]B, 0, len(src))
   806  		for _, src := range src {
   807  			val := fun(src)
   808  			if set.Has(val) {
   809  				continue
   810  			}
   811  			set.Add(val)
   812  			out = append(out, val)
   813  		}
   814  		return out
   815  	}
   816  }
   817  
   818  // Similar to `MapFlat` but excludes duplicates.
   819  func MapFlatUniq[Out ~[]B, A any, B comparable](src []A, fun func(A) Out) Out {
   820  	if src == nil {
   821  		return nil
   822  	}
   823  
   824  	var out Out
   825  	var set Set[B]
   826  	for _, src := range src {
   827  		for _, val := range fun(src) {
   828  			if set.Has(val) {
   829  				continue
   830  			}
   831  			set.Init().Add(val)
   832  			out = append(out, val)
   833  		}
   834  	}
   835  	return out
   836  }
   837  
   838  /*
   839  Takes a slice and "indexes" it by using keys generated by the given function,
   840  returning the resulting map. If the function is nil, returns nil. Compare
   841  `Group` which returns `map[Key][]Val` rather than `map[Key]Val`.
   842  */
   843  func Index[Slice ~[]Val, Key comparable, Val any](src Slice, fun func(Val) Key) map[Key]Val {
   844  	if fun == nil {
   845  		return nil
   846  	}
   847  
   848  	out := make(map[Key]Val, len(src))
   849  	IndexInto(out, src, fun)
   850  	return out
   851  }
   852  
   853  /*
   854  "Indexes" the given slice by adding its values to the given map, keyed by
   855  calling the given function for each value. If the function is nil, does
   856  nothing.
   857  */
   858  func IndexInto[Key comparable, Val any](tar map[Key]Val, src []Val, fun func(Val) Key) {
   859  	if fun == nil {
   860  		return
   861  	}
   862  	for _, val := range src {
   863  		tar[fun(val)] = val
   864  	}
   865  }
   866  
   867  /*
   868  Takes a slice and "indexes" it by converting each element to a key-value pair,
   869  returning the resulting map. If the function is nil or the source slice is
   870  empty, returns nil.
   871  */
   872  func IndexPair[
   873  	Slice ~[]Elem,
   874  	Elem any,
   875  	Key comparable,
   876  	Val any,
   877  ](
   878  	src Slice, fun func(Elem) (Key, Val),
   879  ) map[Key]Val {
   880  	if fun == nil || len(src) <= 0 {
   881  		return nil
   882  	}
   883  
   884  	out := make(map[Key]Val, len(src))
   885  	IndexPairInto(out, src, fun)
   886  	return out
   887  }
   888  
   889  /*
   890  Takes a slice and "indexes" it by adding key-value pairs to the given map,
   891  making key-value pairs by calling the given function for each element. If the
   892  function is nil or the source slice is empty, does nothing.
   893  */
   894  func IndexPairInto[Elem any, Key comparable, Val any](
   895  	tar map[Key]Val,
   896  	src []Elem,
   897  	fun func(Elem) (Key, Val),
   898  ) {
   899  	if fun == nil {
   900  		return
   901  	}
   902  
   903  	for _, src := range src {
   904  		key, val := fun(src)
   905  		tar[key] = val
   906  	}
   907  }
   908  
   909  /*
   910  Groups the elements of the given slice by using keys generated by the given
   911  function, returning the resulting map. If the function is nil, returns nil.
   912  Compare `Index` which returns `map[Key]Val` rather than `map[Key][]Val`.
   913  */
   914  func Group[Slice ~[]Val, Key comparable, Val any](src Slice, fun func(Val) Key) map[Key][]Val {
   915  	if fun == nil {
   916  		return nil
   917  	}
   918  
   919  	out := map[Key][]Val{}
   920  	GroupInto(out, src, fun)
   921  	return out
   922  }
   923  
   924  /*
   925  Groups the elements of the given slice by adding its elements to slices in the
   926  given map, keyed by calling the given function for each element. If the
   927  function is nil, does nothing.
   928  */
   929  func GroupInto[Key comparable, Val any](tar map[Key][]Val, src []Val, fun func(Val) Key) {
   930  	if fun == nil {
   931  		return
   932  	}
   933  	for _, val := range src {
   934  		key := fun(val)
   935  		tar[key] = append(tar[key], val)
   936  	}
   937  }
   938  
   939  /*
   940  Somewhat similar to `Map`. Creates a slice by "mapping" source values to
   941  outputs. Calls the given function N times, passing an index, starting with 0.
   942  */
   943  func Times[A any](src int, fun func(int) A) []A {
   944  	if !(src > 0) || fun == nil {
   945  		return nil
   946  	}
   947  
   948  	buf := make([]A, src)
   949  	for ind := range buf {
   950  		buf[ind] = fun(ind)
   951  	}
   952  	return buf
   953  }
   954  
   955  /*
   956  Similar to `Times` but instead of creating a new slice, appends to an existing
   957  slice.
   958  */
   959  func TimesAppend[Slice ~[]Elem, Elem any](ptr *Slice, src int, fun func(int) Elem) {
   960  	if ptr == nil || fun == nil || !(src > 0) {
   961  		return
   962  	}
   963  
   964  	tar := GrowCap(*ptr, src)
   965  	for ind := range Iter(src) {
   966  		tar = append(tar, fun(ind))
   967  	}
   968  	*ptr = tar
   969  }
   970  
   971  // Same as global `TimesAppend`.
   972  func (self *Slice[A]) TimesAppend(src int, fun func(int) A) {
   973  	TimesAppend(self, src, fun)
   974  }
   975  
   976  // Counts the number of elements for which the given function returns true.
   977  func Count[A any](src []A, fun func(A) bool) int {
   978  	var out int
   979  	if fun != nil {
   980  		for _, src := range src {
   981  			if fun(src) {
   982  				out++
   983  			}
   984  		}
   985  	}
   986  	return out
   987  }
   988  
   989  // Same as global `Count`.
   990  func (self Slice[A]) Count(src []A, fun func(A) bool) int { return Count(self, fun) }
   991  
   992  /*
   993  Folds the given slice by calling the given function for each element,
   994  additionally passing the "accumulator". Returns the resulting accumulator.
   995  */
   996  func Fold[Acc, Val any](src []Val, acc Acc, fun func(Acc, Val) Acc) Acc {
   997  	if fun != nil {
   998  		for _, val := range src {
   999  			acc = fun(acc, val)
  1000  		}
  1001  	}
  1002  	return acc
  1003  }
  1004  
  1005  /*
  1006  Short for "fold zero". Similar to `Fold` but the accumulator automatically
  1007  starts as the zero value of its type.
  1008  */
  1009  func Foldz[Acc, Val any](src []Val, fun func(Acc, Val) Acc) Acc {
  1010  	return Fold(src, Zero[Acc](), fun)
  1011  }
  1012  
  1013  /*
  1014  Similar to `Fold` but uses the first slice element as the accumulator, falling
  1015  back on zero value. The given function is invoked only for 2 or more elements.
  1016  */
  1017  func Fold1[A any](src []A, fun func(A, A) A) A {
  1018  	if len(src) <= 0 {
  1019  		return Zero[A]()
  1020  	}
  1021  	return Fold(src[1:], src[0], fun)
  1022  }
  1023  
  1024  // Returns only the elements for which the given function returned `true`.
  1025  func Filter[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) (out Slice) {
  1026  	FilterAppend(&out, src, fun)
  1027  	return
  1028  }
  1029  
  1030  // Same as global `Filter`.
  1031  func (self Slice[A]) Filter(fun func(A) bool) Slice[A] {
  1032  	return Filter(self, fun)
  1033  }
  1034  
  1035  /*
  1036  Similar to `Filter` but instead of creating a new slice, appends to an existing
  1037  slice.
  1038  */
  1039  func FilterAppend[Tar ~[]Elem, Elem any](ptr *Tar, src []Elem, fun func(Elem) bool) {
  1040  	if ptr == nil || fun == nil {
  1041  		return
  1042  	}
  1043  
  1044  	for _, val := range src {
  1045  		if fun(val) {
  1046  			*ptr = append(*ptr, val)
  1047  		}
  1048  	}
  1049  }
  1050  
  1051  // Same as global `FilterAppend`.
  1052  func (self *Slice[A]) FilterAppend(src []A, fun func(A) bool) {
  1053  	FilterAppend(self, src, fun)
  1054  }
  1055  
  1056  /*
  1057  Inverse of `Filter`. Returns only the elements for which the given function
  1058  returned `false`.
  1059  */
  1060  func Reject[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) (out Slice) {
  1061  	RejectAppend(&out, src, fun)
  1062  	return
  1063  }
  1064  
  1065  // Same as global `Reject`.
  1066  func (self Slice[A]) Reject(fun func(A) bool) Slice[A] {
  1067  	return Reject(self, fun)
  1068  }
  1069  
  1070  /*
  1071  Similar to `Reject` but instead of creating a new slice, appends to an existing
  1072  slice.
  1073  */
  1074  func RejectAppend[Tar ~[]Elem, Elem any](ptr *Tar, src []Elem, fun func(Elem) bool) {
  1075  	if ptr == nil || fun == nil {
  1076  		return
  1077  	}
  1078  
  1079  	for _, val := range src {
  1080  		if !fun(val) {
  1081  			*ptr = append(*ptr, val)
  1082  		}
  1083  	}
  1084  }
  1085  
  1086  // Same as global `RejectAppend`.
  1087  func (self *Slice[A]) RejectAppend(src []A, fun func(A) bool) {
  1088  	RejectAppend(self, src, fun)
  1089  }
  1090  
  1091  /*
  1092  Takes a slice and returns the indexes whose elements satisfy the given function.
  1093  All indexes are within the bounds of the original slice.
  1094  */
  1095  func FilterIndex[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) []int {
  1096  	if fun == nil {
  1097  		return nil
  1098  	}
  1099  
  1100  	var out []int
  1101  	for ind, val := range src {
  1102  		if fun(val) {
  1103  			out = append(out, ind)
  1104  		}
  1105  	}
  1106  	return out
  1107  }
  1108  
  1109  // Same as global `FilterIndex`.
  1110  func (self Slice[A]) FilterIndex(fun func(A) bool) []int {
  1111  	return FilterIndex(self, fun)
  1112  }
  1113  
  1114  /*
  1115  Takes a slice and returns the indexes whose elements are zero.
  1116  All indexes are within the bounds of the original slice.
  1117  */
  1118  func ZeroIndex[Slice ~[]Elem, Elem any](src Slice) []int {
  1119  	return FilterIndex(src, IsZero[Elem])
  1120  }
  1121  
  1122  // Same as global `ZeroIndex`.
  1123  func (self Slice[A]) ZeroIndex() []int { return ZeroIndex(self) }
  1124  
  1125  /*
  1126  Takes a slice and returns the indexes whose elements are non-zero.
  1127  All indexes are within the bounds of the original slice.
  1128  */
  1129  func NotZeroIndex[Slice ~[]Elem, Elem any](src Slice) []int {
  1130  	return FilterIndex(src, IsNotZero[Elem])
  1131  }
  1132  
  1133  // Same as global `NotZeroIndex`.
  1134  func (self Slice[A]) NotZeroIndex() []int { return NotZeroIndex(self) }
  1135  
  1136  // Returns a version of the given slice without any zero values.
  1137  func Compact[Slice ~[]Elem, Elem any](src Slice) Slice {
  1138  	return Filter(src, IsNotZero[Elem])
  1139  }
  1140  
  1141  // Same as global `Compact`.
  1142  func (self Slice[A]) Compact() Slice[A] { return Compact(self) }
  1143  
  1144  /*
  1145  Tests each element by calling the given function and returns the first element
  1146  for which it returns `true`. If none match, returns `-1`.
  1147  */
  1148  func FindIndex[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) int {
  1149  	if fun != nil {
  1150  		for ind, val := range src {
  1151  			if fun(val) {
  1152  				return ind
  1153  			}
  1154  		}
  1155  	}
  1156  	return -1
  1157  }
  1158  
  1159  // Same as global `FindIndex`.
  1160  func (self Slice[A]) FindIndex(fun func(A) bool) int {
  1161  	return FindIndex(self, fun)
  1162  }
  1163  
  1164  /*
  1165  Returns the first element for which the given function returns `true`.
  1166  If nothing is found, returns a zero value. The additional boolean indicates
  1167  whether something was actually found.
  1168  */
  1169  func Found[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) (Elem, bool) {
  1170  	ind := FindIndex(src, fun)
  1171  	if ind >= 0 {
  1172  		return src[ind], true
  1173  	}
  1174  	return Zero[Elem](), false
  1175  }
  1176  
  1177  // Same as global `Found`.
  1178  func (self Slice[A]) Found(fun func(A) bool) (A, bool) {
  1179  	return Found(self, fun)
  1180  }
  1181  
  1182  /*
  1183  Returns the first element for which the given function returns true.
  1184  If nothing is found, returns a zero value.
  1185  */
  1186  func Find[Slice ~[]Elem, Elem any](src Slice, fun func(Elem) bool) Elem {
  1187  	return Get(src, FindIndex(src, fun))
  1188  }
  1189  
  1190  // Same as global `Find`.
  1191  func (self Slice[A]) Find(fun func(A) bool) A { return Find(self, fun) }
  1192  
  1193  /*
  1194  Similar to `Found`, but instead of returning an element, returns the first
  1195  product of the given function for which the returned boolean is true. If
  1196  nothing is procured, returns zero value and false.
  1197  */
  1198  func Procured[Out, Src any](src []Src, fun func(Src) (Out, bool)) (Out, bool) {
  1199  	if fun != nil {
  1200  		for _, src := range src {
  1201  			val, ok := fun(src)
  1202  			if ok {
  1203  				return val, true
  1204  			}
  1205  		}
  1206  	}
  1207  	return Zero[Out](), false
  1208  }
  1209  
  1210  /*
  1211  Similar to `Find`, but instead of returning the first approved element,
  1212  returns the first non-zero result of the given function. If nothing is
  1213  procured, returns a zero value.
  1214  */
  1215  func Procure[Out, Src any](src []Src, fun func(Src) Out) Out {
  1216  	if fun != nil {
  1217  		for _, src := range src {
  1218  			val := fun(src)
  1219  			if IsNotZero(val) {
  1220  				return val
  1221  			}
  1222  		}
  1223  	}
  1224  	return Zero[Out]()
  1225  }
  1226  
  1227  /*
  1228  Returns a version of the given slice with the given values appended unless they
  1229  were already present in the slice. This function only appends; it doesn't
  1230  deduplicate any previously existing values in the slice, nor reorder them.
  1231  */
  1232  func Adjoin[Slice ~[]Elem, Elem comparable](tar Slice, src ...Elem) Slice {
  1233  	RejectAppend(&tar, src, SetOf(tar...).Has)
  1234  	return tar
  1235  }
  1236  
  1237  /*
  1238  Returns a version of the given slice excluding any additionally supplied
  1239  values.
  1240  */
  1241  func Exclude[Slice ~[]Elem, Elem comparable](base Slice, sub ...Elem) Slice {
  1242  	return Reject(base, SetOf(sub...).Has)
  1243  }
  1244  
  1245  /*
  1246  Returns a version of the given slice excluding any additionally supplied
  1247  values.
  1248  */
  1249  func ExcludeFrom[Slice ~[]Elem, Elem comparable](base Slice, sub ...Slice) Slice {
  1250  	return Reject(base, SetFrom(sub...).Has)
  1251  }
  1252  
  1253  // Returns intersection of two slices: elements that occur in both.
  1254  func Intersect[Slice ~[]Elem, Elem comparable](one, two Slice) Slice {
  1255  	return Filter(one, SetOf(two...).Has)
  1256  }
  1257  
  1258  /*
  1259  Combines the given slices, deduplicating their elements and preserving the order
  1260  of first occurrence for each element. As a special case, if the arguments
  1261  contain exactly one non-empty slice, it's returned as-is without deduplication.
  1262  To ensure uniqueness in all cases, call `Uniq`.
  1263  */
  1264  func Union[Slice ~[]Elem, Elem comparable](val ...Slice) Slice {
  1265  	if Count(val, IsNotEmpty[Slice]) == 1 {
  1266  		return Find(val, IsNotEmpty[Slice])
  1267  	}
  1268  
  1269  	var tar Slice
  1270  	var set Set[Elem]
  1271  
  1272  	for _, val := range val {
  1273  		for _, val := range val {
  1274  			if set.Has(val) {
  1275  				continue
  1276  			}
  1277  			tar = append(tar, val)
  1278  			set.Init().Add(val)
  1279  		}
  1280  	}
  1281  
  1282  	return tar
  1283  }
  1284  
  1285  /*
  1286  Deduplicates the elements of the given slice, preserving the order of initial
  1287  occurrence for each element. The output is always either nil or a newly
  1288  allocated slice with at least one element. Compare `UniqBy` which compares
  1289  elements by keys obtained by calling the given function.
  1290  */
  1291  func Uniq[Slice ~[]Elem, Elem comparable](src Slice) Slice {
  1292  	var tar Slice
  1293  	var set Set[Elem]
  1294  
  1295  	for _, val := range src {
  1296  		if set.Has(val) {
  1297  			continue
  1298  		}
  1299  		tar = append(tar, val)
  1300  		set.Init().Add(val)
  1301  	}
  1302  
  1303  	return tar
  1304  }
  1305  
  1306  /*
  1307  Deduplicates the elements of the given slice on keys obtained by calling the
  1308  given function for each element, and preserving the order of initial occurrence
  1309  for each element. If the function is nil, returns nil. The output is always
  1310  either nil or a newly allocated slice with at least one element. Compare `Uniq`
  1311  which compares the elements themselves.
  1312  */
  1313  func UniqBy[Slice ~[]Elem, Elem any, Key comparable](src Slice, fun func(Elem) Key) Slice {
  1314  	if fun == nil {
  1315  		return nil
  1316  	}
  1317  
  1318  	var tar Slice
  1319  	var set Set[Key]
  1320  
  1321  	for _, val := range src {
  1322  		key := fun(val)
  1323  		if set.Has(key) {
  1324  			continue
  1325  		}
  1326  		tar = append(tar, val)
  1327  		set.Init().Add(key)
  1328  	}
  1329  
  1330  	return tar
  1331  }
  1332  
  1333  /*
  1334  Variant of `Has` that uses `Equal` rather than `==` to compare elements. Should
  1335  be used ONLY for very small inputs: no more than a few tens of elements. For
  1336  larger data, consider using indexed data structures such as sets and maps.
  1337  */
  1338  func HasEqual[A any](src []A, val A) bool {
  1339  	return Some(src, func(elem A) bool { return Equal(elem, val) })
  1340  }
  1341  
  1342  // Same as global `HasEqual`.
  1343  func (self Slice[A]) HasEqual(val A) bool { return HasEqual(self, val) }
  1344  
  1345  /*
  1346  True if the given slice contains the given value. Should be used ONLY for very
  1347  small inputs: no more than a few tens of elements. For larger data, consider
  1348  using indexed data structures such as sets and maps. Inverse of `NotHas`.
  1349  */
  1350  func Has[A comparable](src []A, val A) bool {
  1351  	return Some(src, func(elem A) bool { return elem == val })
  1352  }
  1353  
  1354  /*
  1355  True if the given slice does not contain the given value. Should be used ONLY
  1356  for very small inputs: no more than a few tens of elements. For larger data,
  1357  consider using indexed data structures such as sets and maps. Inverse of `Has`.
  1358  The awkward name is chosen for symmetry with `gtest.NotHas` where it fits more
  1359  naturally due to conventions for assertion naming.
  1360  */
  1361  func NotHas[A comparable](src []A, val A) bool { return !Has(src, val) }
  1362  
  1363  /*
  1364  True if the first slice has all elements from the second slice. In other words,
  1365  true if A is a superset of B: A >= B.
  1366  */
  1367  func HasEvery[A comparable](src, exp []A) bool {
  1368  	return Every(exp, SetOf(src...).Has)
  1369  }
  1370  
  1371  /*
  1372  True if the first slice has some elements from the second slice. In other words,
  1373  true if the sets A and B intersect.
  1374  */
  1375  func HasSome[A comparable](src, exp []A) bool {
  1376  	return Some(exp, SetOf(src...).Has)
  1377  }
  1378  
  1379  /*
  1380  True if the first slice has NO elements from the second slice. In other words,
  1381  true if the sets A and B don't intersect.
  1382  */
  1383  func HasNone[A comparable](src, exp []A) bool {
  1384  	return None(exp, SetOf(src...).Has)
  1385  }
  1386  
  1387  /*
  1388  True if the given function returns true for any element of the given slice.
  1389  False if the function is nil. False if the slice is empty.
  1390  */
  1391  func Some[A any](src []A, fun func(A) bool) bool {
  1392  	if fun == nil {
  1393  		return false
  1394  	}
  1395  	for _, val := range src {
  1396  		if fun(val) {
  1397  			return true
  1398  		}
  1399  	}
  1400  	return false
  1401  }
  1402  
  1403  // Same as global `Some`.
  1404  func (self Slice[A]) Some(fun func(A) bool) bool { return Some(self, fun) }
  1405  
  1406  /*
  1407  True if the given function returns false for every element of the given slice,
  1408  or if the slice is empty, or if the function is nil. Exact inverse of `Some`.
  1409  */
  1410  func None[A any](src []A, fun func(A) bool) bool { return !Some(src, fun) }
  1411  
  1412  // Same as global `None`.
  1413  func (self Slice[A]) None(fun func(A) bool) bool { return None(self, fun) }
  1414  
  1415  /*
  1416  Utility for comparing slices pairwise. Returns true if the slices have the same
  1417  length and the function returns true for at least one pair.
  1418  */
  1419  func SomePair[A any](one, two []A, fun func(A, A) bool) bool {
  1420  	if len(one) != len(two) || fun == nil {
  1421  		return false
  1422  	}
  1423  	for ind := range one {
  1424  		if fun(one[ind], two[ind]) {
  1425  			return true
  1426  		}
  1427  	}
  1428  	return false
  1429  }
  1430  
  1431  /*
  1432  True if the given function returns true for every element of the given slice.
  1433  False if the function is nil. True if the slice is empty.
  1434  */
  1435  func Every[A any](src []A, fun func(A) bool) bool {
  1436  	if fun == nil {
  1437  		return false
  1438  	}
  1439  	for _, val := range src {
  1440  		if !fun(val) {
  1441  			return false
  1442  		}
  1443  	}
  1444  	return true
  1445  }
  1446  
  1447  // Same as global `Every`.
  1448  func (self Slice[A]) Every(fun func(A) bool) bool { return Every(self, fun) }
  1449  
  1450  /*
  1451  Utility for comparing slices pairwise. Returns true if the slices have the same
  1452  length and the function returns true for every pair.
  1453  */
  1454  func EveryPair[A any](one, two []A, fun func(A, A) bool) bool {
  1455  	if len(one) != len(two) || fun == nil {
  1456  		return false
  1457  	}
  1458  	for ind := range one {
  1459  		if !fun(one[ind], two[ind]) {
  1460  			return false
  1461  		}
  1462  	}
  1463  	return true
  1464  }
  1465  
  1466  // Concatenates the inputs. If every input is nil, output is nil.
  1467  func Concat[Slice ~[]Elem, Elem any](val ...Slice) Slice {
  1468  	if Every(val, IsZero[Slice]) {
  1469  		return nil
  1470  	}
  1471  
  1472  	buf := make(Slice, 0, Lens(val...))
  1473  	for _, val := range val {
  1474  		buf = append(buf, val...)
  1475  	}
  1476  	return buf
  1477  }
  1478  
  1479  /*
  1480  Tool for comparing slice elements pairwise. Iterates left-to-right, invoking the
  1481  given function for each element pair. If the function is nil, returns false. If
  1482  there are 0 or 1 elements, returns true. If every comparison returned true,
  1483  returns true. Otherwise returns false.
  1484  */
  1485  func IsSorted[A any](src []A, fun func(A, A) bool) bool {
  1486  	if fun == nil {
  1487  		return false
  1488  	}
  1489  
  1490  	switch len(src) {
  1491  	case 0, 1:
  1492  		return true
  1493  
  1494  	case 2:
  1495  		return fun(src[0], src[1])
  1496  
  1497  	default:
  1498  		prev := src[0]
  1499  		for _, next := range src[1:] {
  1500  			if fun(prev, next) {
  1501  				prev = next
  1502  				continue
  1503  			}
  1504  			return false
  1505  		}
  1506  		return true
  1507  	}
  1508  }
  1509  
  1510  // Sorts a slice of comparable primitives. For non-primitives, see `Sort`.
  1511  func SortPrim[A LesserPrim](val []A) { SortablePrim[A](val).Sort() }
  1512  
  1513  /*
  1514  Sorts a slice of comparable primitives, mutating and returning that slice.
  1515  For non-primitives, see `Sort`.
  1516  */
  1517  func SortedPrim[Slice ~[]Elem, Elem LesserPrim](val Slice) Slice {
  1518  	return Slice(SortablePrim[Elem](val).Sorted())
  1519  }
  1520  
  1521  // Slice of primitives that implements `sort.Interface`.
  1522  type SortablePrim[A LesserPrim] []A
  1523  
  1524  // Implement `sort.Interface`.
  1525  func (self SortablePrim[_]) Len() int { return len(self) }
  1526  
  1527  // Implement `sort.Interface`.
  1528  func (self SortablePrim[_]) Less(one, two int) bool { return self[one] < self[two] }
  1529  
  1530  // Implement `sort.Interface`.
  1531  func (self SortablePrim[_]) Swap(one, two int) { Swap(self, one, two) }
  1532  
  1533  // Sorts the receiver, mutating it.
  1534  func (self SortablePrim[_]) Sort() { sort.Stable(NoEscUnsafe(sort.Interface(self))) }
  1535  
  1536  // Sorts the receiver, mutating and returning it.
  1537  func (self SortablePrim[A]) Sorted() SortablePrim[A] {
  1538  	self.Sort()
  1539  	return self
  1540  }
  1541  
  1542  // Sorts a slice of comparable non-primitives. For primitives, see `SortPrim`.
  1543  func Sort[A Lesser[A]](val []A) { Sortable[A](val).Sort() }
  1544  
  1545  /*
  1546  Sorts a slice of comparable values, mutating and returning that slice.
  1547  For primitives, see `SortedPrim`.
  1548  */
  1549  func Sorted[Slice ~[]Elem, Elem Lesser[Elem]](val Slice) Slice {
  1550  	return Slice(Sortable[Elem](val).Sorted())
  1551  }
  1552  
  1553  // Slice of non-primitives that implements `sort.Interface`.
  1554  type Sortable[A Lesser[A]] []A
  1555  
  1556  // Implement `sort.Interface`.
  1557  func (self Sortable[_]) Len() int { return len(self) }
  1558  
  1559  // Implement `sort.Interface`.
  1560  func (self Sortable[_]) Less(one, two int) bool { return self[one].Less(self[two]) }
  1561  
  1562  // Implement `sort.Interface`.
  1563  func (self Sortable[_]) Swap(one, two int) { Swap(self, one, two) }
  1564  
  1565  // Sorts the receiver, mutating it.
  1566  func (self Sortable[_]) Sort() { sort.Stable(NoEscUnsafe(sort.Interface(self))) }
  1567  
  1568  // Sorts the receiver, mutating and returning it.
  1569  func (self Sortable[A]) Sorted() Sortable[A] {
  1570  	self.Sort()
  1571  	return self
  1572  }
  1573  
  1574  // Reverses the given slice in-place, mutating it.
  1575  func Reverse[A any](val []A) {
  1576  	ind0 := 0
  1577  	ind1 := len(val) - 1
  1578  
  1579  	for ind0 < ind1 {
  1580  		val[ind0], val[ind1] = val[ind1], val[ind0]
  1581  		ind0++
  1582  		ind1--
  1583  	}
  1584  }
  1585  
  1586  // Same as global `Reverse`.
  1587  func (self Slice[_]) Reverse() { Reverse(self) }
  1588  
  1589  // Reverses the given slice in-place, mutating it and returning that slice.
  1590  func Reversed[Slice ~[]Elem, Elem any](val Slice) Slice {
  1591  	Reverse(val)
  1592  	return val
  1593  }
  1594  
  1595  // Same as global `Reversed`.
  1596  func (self Slice[A]) Reversed() Slice[A] { return Reversed(self) }
  1597  
  1598  // Swaps the two elements at the given indexes in the given slice.
  1599  func Swap[Slice ~[]Elem, Elem any](tar Slice, one, two int) {
  1600  	tar[one], tar[two] = tar[two], tar[one]
  1601  }
  1602  
  1603  // Same as global `Swap`.
  1604  func (self Slice[A]) Swap(one, two int) { Swap(self, one, two) }