github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/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  	pointer := uintptr(unsafe.Pointer(&obj))
   163  	//nolint:staticcheck
   164  	//goland:noinspection GoVetUnsafePointer
   165  	return *(*T)(unsafe.Pointer(pointer))
   166  }
   167  
   168  func KeepAlive(obj any) {
   169  	runtime.KeepAlive(obj)
   170  }
   171  
   172  func Uniq[T comparable](arr []T) []T {
   173  	result := make([]T, 0, len(arr))
   174  	seen := make(map[T]struct{}, len(arr))
   175  
   176  	for _, item := range arr {
   177  		if _, ok := seen[item]; ok {
   178  			continue
   179  		}
   180  
   181  		seen[item] = struct{}{}
   182  		result = append(result, item)
   183  	}
   184  
   185  	return result
   186  }
   187  
   188  func UniqBy[T any, C comparable](arr []T, block func(it T) C) []T {
   189  	result := make([]T, 0, len(arr))
   190  	seen := make(map[C]struct{}, len(arr))
   191  
   192  	for _, item := range arr {
   193  		c := block(item)
   194  		if _, ok := seen[c]; ok {
   195  			continue
   196  		}
   197  
   198  		seen[c] = struct{}{}
   199  		result = append(result, item)
   200  	}
   201  
   202  	return result
   203  }
   204  
   205  func SortBy[T any, C constraints.Ordered](arr []T, block func(it T) C) {
   206  	sort.Slice(arr, func(i, j int) bool {
   207  		return block(arr[i]) < block(arr[j])
   208  	})
   209  }
   210  
   211  func MinBy[T any, C constraints.Ordered](arr []T, block func(it T) C) T {
   212  	var min T
   213  	var minValue C
   214  	if len(arr) == 0 {
   215  		return min
   216  	}
   217  	min = arr[0]
   218  	minValue = block(min)
   219  	for i := 1; i < len(arr); i++ {
   220  		item := arr[i]
   221  		value := block(item)
   222  		if value < minValue {
   223  			min = item
   224  			minValue = value
   225  		}
   226  	}
   227  	return min
   228  }
   229  
   230  func MaxBy[T any, C constraints.Ordered](arr []T, block func(it T) C) T {
   231  	var max T
   232  	var maxValue C
   233  	if len(arr) == 0 {
   234  		return max
   235  	}
   236  	max = arr[0]
   237  	maxValue = block(max)
   238  	for i := 1; i < len(arr); i++ {
   239  		item := arr[i]
   240  		value := block(item)
   241  		if value > maxValue {
   242  			max = item
   243  			maxValue = value
   244  		}
   245  	}
   246  	return max
   247  }
   248  
   249  func FilterIsInstance[T any, N any](arr []T, block func(it T) (N, bool)) []N {
   250  	var retArr []N
   251  	for _, it := range arr {
   252  		if n, isN := block(it); isN {
   253  			retArr = append(retArr, n)
   254  		}
   255  	}
   256  	return retArr
   257  }
   258  
   259  func Reverse[T any](arr []T) []T {
   260  	length := len(arr)
   261  	half := length / 2
   262  
   263  	for i := 0; i < half; i = i + 1 {
   264  		j := length - 1 - i
   265  		arr[i], arr[j] = arr[j], arr[i]
   266  	}
   267  
   268  	return arr
   269  }
   270  
   271  func Done(ctx context.Context) bool {
   272  	select {
   273  	case <-ctx.Done():
   274  		return true
   275  	default:
   276  		return false
   277  	}
   278  }
   279  
   280  func Error(_ any, err error) error {
   281  	return err
   282  }
   283  
   284  func Must(errs ...error) {
   285  	for _, err := range errs {
   286  		if err != nil {
   287  			panic(err)
   288  		}
   289  	}
   290  }
   291  
   292  func Must1[T any](result T, err error) T {
   293  	if err != nil {
   294  		panic(err)
   295  	}
   296  	return result
   297  }
   298  
   299  func Must2[T any, T2 any](result T, result2 T2, err error) (T, T2) {
   300  	if err != nil {
   301  		panic(err)
   302  	}
   303  	return result, result2
   304  }
   305  
   306  // Deprecated: use E.Errors
   307  func AnyError(errs ...error) error {
   308  	for _, err := range errs {
   309  		if err != nil {
   310  			return err
   311  		}
   312  	}
   313  	return nil
   314  }
   315  
   316  func PtrOrNil[T any](ptr *T) any {
   317  	if ptr == nil {
   318  		return nil
   319  	}
   320  	return ptr
   321  }
   322  
   323  func PtrValueOrDefault[T any](ptr *T) T {
   324  	if ptr == nil {
   325  		return DefaultValue[T]()
   326  	}
   327  	return *ptr
   328  }
   329  
   330  func IsEmpty[T comparable](obj T) bool {
   331  	return obj == DefaultValue[T]()
   332  }
   333  
   334  func DefaultValue[T any]() T {
   335  	var defaultValue T
   336  	return defaultValue
   337  }
   338  
   339  func Ptr[T any](obj T) *T {
   340  	return &obj
   341  }
   342  
   343  func Close(closers ...any) error {
   344  	var retErr error
   345  	for _, closer := range closers {
   346  		if closer == nil {
   347  			continue
   348  		}
   349  		switch c := closer.(type) {
   350  		case io.Closer:
   351  			err := c.Close()
   352  			if err != nil {
   353  				retErr = err
   354  			}
   355  			continue
   356  		case WithUpstream:
   357  			err := Close(c.Upstream())
   358  			if err != nil {
   359  				retErr = err
   360  			}
   361  		}
   362  	}
   363  	return retErr
   364  }
   365  
   366  type Starter interface {
   367  	Start() error
   368  }
   369  
   370  func Start(starters ...any) error {
   371  	for _, rawStarter := range starters {
   372  		if rawStarter == nil {
   373  			continue
   374  		}
   375  		if starter, isStarter := rawStarter.(Starter); isStarter {
   376  			err := starter.Start()
   377  			if err != nil {
   378  				return err
   379  			}
   380  		}
   381  	}
   382  	return nil
   383  }