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 }