sort.go raw

   1  // Copyright 2022 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  import (
   8  	"cmp"
   9  	"slices"
  10  )
  11  
  12  // Sort sorts a slice of any ordered type in ascending order.
  13  // When sorting floating-point numbers, NaNs are ordered before other values.
  14  //
  15  //go:fix inline
  16  func Sort[S ~[]E, E cmp.Ordered](x S) {
  17  	slices.Sort(x)
  18  }
  19  
  20  // SortFunc sorts the slice x in ascending order as determined by the cmp
  21  // function. This sort is not guaranteed to be stable.
  22  // cmp(a, b) should return a negative number when a < b, a positive number when
  23  // a > b and zero when a == b or when a is not comparable to b in the sense
  24  // of the formal definition of Strict Weak Ordering.
  25  //
  26  // SortFunc requires that cmp is a strict weak ordering.
  27  // See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
  28  // To indicate 'uncomparable', return 0 from the function.
  29  //
  30  //go:fix inline
  31  func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
  32  	slices.SortFunc(x, cmp)
  33  }
  34  
  35  // SortStableFunc sorts the slice x while keeping the original order of equal
  36  // elements, using cmp to compare elements in the same way as [SortFunc].
  37  //
  38  //go:fix inline
  39  func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
  40  	slices.SortStableFunc(x, cmp)
  41  }
  42  
  43  // IsSorted reports whether x is sorted in ascending order.
  44  //
  45  //go:fix inline
  46  func IsSorted[S ~[]E, E cmp.Ordered](x S) bool {
  47  	return slices.IsSorted(x)
  48  }
  49  
  50  // IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
  51  // comparison function as defined by [SortFunc].
  52  //
  53  //go:fix inline
  54  func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
  55  	return slices.IsSortedFunc(x, cmp)
  56  }
  57  
  58  // Min returns the minimal value in x. It panics if x is empty.
  59  // For floating-point numbers, Min propagates NaNs (any NaN value in x
  60  // forces the output to be NaN).
  61  //
  62  //go:fix inline
  63  func Min[S ~[]E, E cmp.Ordered](x S) E {
  64  	return slices.Min(x)
  65  }
  66  
  67  // MinFunc returns the minimal value in x, using cmp to compare elements.
  68  // It panics if x is empty. If there is more than one minimal element
  69  // according to the cmp function, MinFunc returns the first one.
  70  //
  71  //go:fix inline
  72  func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
  73  	return slices.MinFunc(x, cmp)
  74  }
  75  
  76  // Max returns the maximal value in x. It panics if x is empty.
  77  // For floating-point E, Max propagates NaNs (any NaN value in x
  78  // forces the output to be NaN).
  79  //
  80  //go:fix inline
  81  func Max[S ~[]E, E cmp.Ordered](x S) E {
  82  	return slices.Max(x)
  83  }
  84  
  85  // MaxFunc returns the maximal value in x, using cmp to compare elements.
  86  // It panics if x is empty. If there is more than one maximal element
  87  // according to the cmp function, MaxFunc returns the first one.
  88  //
  89  //go:fix inline
  90  func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
  91  	return slices.MaxFunc(x, cmp)
  92  }
  93  
  94  // BinarySearch searches for target in a sorted slice and returns the position
  95  // where target is found, or the position where target would appear in the
  96  // sort order; it also returns a bool saying whether the target is really found
  97  // in the slice. The slice must be sorted in increasing order.
  98  //
  99  //go:fix inline
 100  func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) {
 101  	return slices.BinarySearch(x, target)
 102  }
 103  
 104  // BinarySearchFunc works like [BinarySearch], but uses a custom comparison
 105  // function. The slice must be sorted in increasing order, where "increasing"
 106  // is defined by cmp. cmp should return 0 if the slice element matches
 107  // the target, a negative number if the slice element precedes the target,
 108  // or a positive number if the slice element follows the target.
 109  // cmp must implement the same ordering as the slice, such that if
 110  // cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
 111  //
 112  //go:fix inline
 113  func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
 114  	return slices.BinarySearchFunc(x, target, cmp)
 115  }
 116