github.com/sagernet/sing@v0.2.6/common/cond.go (about)

     1  package common
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"runtime"
     7  	"sort"
     8  	"unsafe"
     9  
    10  	"github.com/sagernet/sing/common/x/constraints"
    11  )
    12  
    13  func Any[T any](array []T, block func(it T) bool) bool {
    14  	for _, it := range array {
    15  		if block(it) {
    16  			return true
    17  		}
    18  	}
    19  	return false
    20  }
    21  
    22  func AnyIndexed[T any](array []T, block func(index int, it T) bool) bool {
    23  	for index, it := range array {
    24  		if block(index, it) {
    25  			return true
    26  		}
    27  	}
    28  	return false
    29  }
    30  
    31  func All[T any](array []T, block func(it T) bool) bool {
    32  	for _, it := range array {
    33  		if !block(it) {
    34  			return false
    35  		}
    36  	}
    37  	return true
    38  }
    39  
    40  func AllIndexed[T any](array []T, block func(index int, it T) bool) bool {
    41  	for index, it := range array {
    42  		if !block(index, it) {
    43  			return false
    44  		}
    45  	}
    46  	return true
    47  }
    48  
    49  func Contains[T comparable](arr []T, target T) bool {
    50  	for index := range arr {
    51  		if target == arr[index] {
    52  			return true
    53  		}
    54  	}
    55  	return false
    56  }
    57  
    58  func Map[T any, N any](arr []T, block func(it T) N) []N {
    59  	retArr := make([]N, 0, len(arr))
    60  	for index := range arr {
    61  		retArr = append(retArr, block(arr[index]))
    62  	}
    63  	return retArr
    64  }
    65  
    66  func MapIndexed[T any, N any](arr []T, block func(index int, it T) N) []N {
    67  	retArr := make([]N, 0, len(arr))
    68  	for index := range arr {
    69  		retArr = append(retArr, block(index, arr[index]))
    70  	}
    71  	return retArr
    72  }
    73  
    74  func FlatMap[T any, N any](arr []T, block func(it T) []N) []N {
    75  	var retAddr []N
    76  	for _, item := range arr {
    77  		retAddr = append(retAddr, block(item)...)
    78  	}
    79  	return retAddr
    80  }
    81  
    82  func FlatMapIndexed[T any, N any](arr []T, block func(index int, it T) []N) []N {
    83  	var retAddr []N
    84  	for index, item := range arr {
    85  		retAddr = append(retAddr, block(index, item)...)
    86  	}
    87  	return retAddr
    88  }
    89  
    90  func Filter[T any](arr []T, block func(it T) bool) []T {
    91  	var retArr []T
    92  	for _, it := range arr {
    93  		if block(it) {
    94  			retArr = append(retArr, it)
    95  		}
    96  	}
    97  	return retArr
    98  }
    99  
   100  func FilterNotNil[T any](arr []T) []T {
   101  	return Filter(arr, func(it T) bool {
   102  		var anyIt any = it
   103  		return anyIt != nil
   104  	})
   105  }
   106  
   107  func FilterNotDefault[T comparable](arr []T) []T {
   108  	var defaultValue T
   109  	return Filter(arr, func(it T) bool {
   110  		return it != defaultValue
   111  	})
   112  }
   113  
   114  func FilterIndexed[T any](arr []T, block func(index int, it T) bool) []T {
   115  	var retArr []T
   116  	for index, it := range arr {
   117  		if block(index, it) {
   118  			retArr = append(retArr, it)
   119  		}
   120  	}
   121  	return retArr
   122  }
   123  
   124  func Find[T any](arr []T, block func(it T) bool) T {
   125  	for _, it := range arr {
   126  		if block(it) {
   127  			return it
   128  		}
   129  	}
   130  	return DefaultValue[T]()
   131  }
   132  
   133  func FindIndexed[T any](arr []T, block func(index int, it T) bool) T {
   134  	for index, it := range arr {
   135  		if block(index, it) {
   136  			return it
   137  		}
   138  	}
   139  	return DefaultValue[T]()
   140  }
   141  
   142  func Index[T any](arr []T, block func(it T) bool) int {
   143  	for index, it := range arr {
   144  		if block(it) {
   145  			return index
   146  		}
   147  	}
   148  	return -1
   149  }
   150  
   151  func IndexIndexed[T any](arr []T, block func(index int, it T) bool) int {
   152  	for index, it := range arr {
   153  		if block(index, it) {
   154  			return index
   155  		}
   156  	}
   157  	return -1
   158  }
   159  
   160  //go:norace
   161  func Dup[T any](obj T) T {
   162  	if UnsafeBuffer {
   163  		pointer := uintptr(unsafe.Pointer(&obj))
   164  		//nolint:staticcheck
   165  		//goland:noinspection GoVetUnsafePointer
   166  		return *(*T)(unsafe.Pointer(pointer))
   167  	} else {
   168  		return obj
   169  	}
   170  }
   171  
   172  func KeepAlive(obj any) {
   173  	if UnsafeBuffer {
   174  		runtime.KeepAlive(obj)
   175  	}
   176  }
   177  
   178  func Uniq[T comparable](arr []T) []T {
   179  	result := make([]T, 0, len(arr))
   180  	seen := make(map[T]struct{}, len(arr))
   181  
   182  	for _, item := range arr {
   183  		if _, ok := seen[item]; ok {
   184  			continue
   185  		}
   186  
   187  		seen[item] = struct{}{}
   188  		result = append(result, item)
   189  	}
   190  
   191  	return result
   192  }
   193  
   194  func UniqBy[T any, C comparable](arr []T, block func(it T) C) []T {
   195  	result := make([]T, 0, len(arr))
   196  	seen := make(map[C]struct{}, len(arr))
   197  
   198  	for _, item := range arr {
   199  		c := block(item)
   200  		if _, ok := seen[c]; ok {
   201  			continue
   202  		}
   203  
   204  		seen[c] = struct{}{}
   205  		result = append(result, item)
   206  	}
   207  
   208  	return result
   209  }
   210  
   211  func SortBy[T any, C constraints.Ordered](arr []T, block func(it T) C) {
   212  	sort.Slice(arr, func(i, j int) bool {
   213  		return block(arr[i]) < block(arr[j])
   214  	})
   215  }
   216  
   217  func MinBy[T any, C constraints.Ordered](arr []T, block func(it T) C) T {
   218  	var min T
   219  	var minValue C
   220  	if len(arr) == 0 {
   221  		return min
   222  	}
   223  	min = arr[0]
   224  	minValue = block(min)
   225  	for i := 1; i < len(arr); i++ {
   226  		item := arr[i]
   227  		value := block(item)
   228  		if value < minValue {
   229  			min = item
   230  			minValue = value
   231  		}
   232  	}
   233  	return min
   234  }
   235  
   236  func MaxBy[T any, C constraints.Ordered](arr []T, block func(it T) C) T {
   237  	var max T
   238  	var maxValue C
   239  	if len(arr) == 0 {
   240  		return max
   241  	}
   242  	max = arr[0]
   243  	maxValue = block(max)
   244  	for i := 1; i < len(arr); i++ {
   245  		item := arr[i]
   246  		value := block(item)
   247  		if value > maxValue {
   248  			max = item
   249  			maxValue = value
   250  		}
   251  	}
   252  	return max
   253  }
   254  
   255  func FilterIsInstance[T any, N any](arr []T, block func(it T) (N, bool)) []N {
   256  	var retArr []N
   257  	for _, it := range arr {
   258  		if n, isN := block(it); isN {
   259  			retArr = append(retArr, n)
   260  		}
   261  	}
   262  	return retArr
   263  }
   264  
   265  func Reverse[T any](arr []T) []T {
   266  	length := len(arr)
   267  	half := length / 2
   268  
   269  	for i := 0; i < half; i = i + 1 {
   270  		j := length - 1 - i
   271  		arr[i], arr[j] = arr[j], arr[i]
   272  	}
   273  
   274  	return arr
   275  }
   276  
   277  func Done(ctx context.Context) bool {
   278  	select {
   279  	case <-ctx.Done():
   280  		return true
   281  	default:
   282  		return false
   283  	}
   284  }
   285  
   286  func Error(_ any, err error) error {
   287  	return err
   288  }
   289  
   290  func Must(errs ...error) {
   291  	for _, err := range errs {
   292  		if err != nil {
   293  			panic(err)
   294  		}
   295  	}
   296  }
   297  
   298  func Must1[T any](result T, err error) T {
   299  	if err != nil {
   300  		panic(err)
   301  	}
   302  	return result
   303  }
   304  
   305  func Must2[T any, T2 any](result T, result2 T2, err error) (T, T2) {
   306  	if err != nil {
   307  		panic(err)
   308  	}
   309  	return result, result2
   310  }
   311  
   312  // Deprecated: use E.Errors
   313  func AnyError(errs ...error) error {
   314  	for _, err := range errs {
   315  		if err != nil {
   316  			return err
   317  		}
   318  	}
   319  	return nil
   320  }
   321  
   322  func PtrOrNil[T any](ptr *T) any {
   323  	if ptr == nil {
   324  		return nil
   325  	}
   326  	return ptr
   327  }
   328  
   329  func PtrValueOrDefault[T any](ptr *T) T {
   330  	if ptr == nil {
   331  		return DefaultValue[T]()
   332  	}
   333  	return *ptr
   334  }
   335  
   336  func IsEmpty[T comparable](obj T) bool {
   337  	return obj == DefaultValue[T]()
   338  }
   339  
   340  func DefaultValue[T any]() T {
   341  	var defaultValue T
   342  	return defaultValue
   343  }
   344  
   345  func Close(closers ...any) error {
   346  	var retErr error
   347  	for _, closer := range closers {
   348  		if closer == nil {
   349  			continue
   350  		}
   351  		switch c := closer.(type) {
   352  		case io.Closer:
   353  			err := c.Close()
   354  			if err != nil {
   355  				retErr = err
   356  			}
   357  			continue
   358  		case WithUpstream:
   359  			err := Close(c.Upstream())
   360  			if err != nil {
   361  				retErr = err
   362  			}
   363  		}
   364  	}
   365  	return retErr
   366  }
   367  
   368  type Starter interface {
   369  	Start() error
   370  }
   371  
   372  func Start(starters ...any) error {
   373  	for _, rawStarter := range starters {
   374  		if rawStarter == nil {
   375  			continue
   376  		}
   377  		if starter, isStarter := rawStarter.(Starter); isStarter {
   378  			err := starter.Start()
   379  			if err != nil {
   380  				return err
   381  			}
   382  		}
   383  	}
   384  	return nil
   385  }