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 }