-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//go:build go1.21 | ||
|
||
package common | ||
|
||
import ( | ||
"cmp" | ||
) | ||
|
||
func Min[T cmp.Ordered](x, y T) T { | ||
Check failure on line 9 in common/minmax.go
|
||
return min(x, y) | ||
} | ||
|
||
func Max[T cmp.Ordered](x, y T) T { | ||
Check failure on line 13 in common/minmax.go
|
||
return max(x, y) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package common | ||
|
||
import "github.com/sagernet/sing/common/x/constraints" | ||
|
||
func Min[T constraints.Ordered](x, y T) T { | ||
Check failure on line 5 in common/minmax_compat.go
|
||
if x < y { | ||
return x | ||
} | ||
return y | ||
} | ||
|
||
func Max[T constraints.Ordered](x, y T) T { | ||
Check failure on line 12 in common/minmax_compat.go
|
||
if x < y { | ||
return y | ||
} | ||
return x | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//go:build go1.21 | ||
|
||
package common | ||
|
||
import "sync" | ||
|
||
// OnceFunc is a wrapper around sync.OnceFunc. | ||
func OnceFunc(f func()) func() { | ||
return sync.OnceFunc(f) | ||
} | ||
|
||
// OnceValue is a wrapper around sync.OnceValue. | ||
func OnceValue[T any](f func() T) func() T { | ||
return sync.OnceValue(f) | ||
} | ||
|
||
// OnceValues is a wrapper around sync.OnceValues. | ||
func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { | ||
return sync.OnceValues(f) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright 2022 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
//go:build go1.20 && !go1.21 | ||
|
||
package common | ||
|
||
import "sync" | ||
|
||
// OnceFunc returns a function that invokes f only once. The returned function | ||
// may be called concurrently. | ||
// | ||
// If f panics, the returned function will panic with the same value on every call. | ||
func OnceFunc(f func()) func() { | ||
var ( | ||
once sync.Once | ||
valid bool | ||
p any | ||
) | ||
// Construct the inner closure just once to reduce costs on the fast path. | ||
g := func() { | ||
defer func() { | ||
p = recover() | ||
if !valid { | ||
// Re-panic immediately so on the first call the user gets a | ||
// complete stack trace into f. | ||
panic(p) | ||
} | ||
}() | ||
f() | ||
f = nil // Do not keep f alive after invoking it. | ||
valid = true // Set only if f does not panic. | ||
} | ||
return func() { | ||
once.Do(g) | ||
if !valid { | ||
panic(p) | ||
} | ||
} | ||
} | ||
|
||
// OnceValue returns a function that invokes f only once and returns the value | ||
// returned by f. The returned function may be called concurrently. | ||
// | ||
// If f panics, the returned function will panic with the same value on every call. | ||
func OnceValue[T any](f func() T) func() T { | ||
var ( | ||
once sync.Once | ||
valid bool | ||
p any | ||
result T | ||
) | ||
g := func() { | ||
defer func() { | ||
p = recover() | ||
if !valid { | ||
panic(p) | ||
} | ||
}() | ||
result = f() | ||
f = nil | ||
valid = true | ||
} | ||
return func() T { | ||
once.Do(g) | ||
if !valid { | ||
panic(p) | ||
} | ||
return result | ||
} | ||
} | ||
|
||
// OnceValues returns a function that invokes f only once and returns the values | ||
// returned by f. The returned function may be called concurrently. | ||
// | ||
// If f panics, the returned function will panic with the same value on every call. | ||
func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) { | ||
var ( | ||
once sync.Once | ||
valid bool | ||
p any | ||
r1 T1 | ||
r2 T2 | ||
) | ||
g := func() { | ||
defer func() { | ||
p = recover() | ||
if !valid { | ||
panic(p) | ||
} | ||
}() | ||
r1, r2 = f() | ||
f = nil | ||
valid = true | ||
} | ||
return func() (T1, T2) { | ||
once.Do(g) | ||
if !valid { | ||
panic(p) | ||
} | ||
return r1, r2 | ||
} | ||
} |