Skip to content

Commit d59ac57

Browse files
committed
Add go1.21 compat funcs
1 parent c635464 commit d59ac57

File tree

4 files changed

+158
-0
lines changed

4 files changed

+158
-0
lines changed

common/minmax.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build go1.21
2+
3+
package common
4+
5+
import (
6+
"cmp"
7+
)
8+
9+
func Min[T cmp.Ordered](x, y T) T {
10+
return min(x, y)
11+
}
12+
13+
func Max[T cmp.Ordered](x, y T) T {
14+
return max(x, y)
15+
}

common/minmax_compat.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//go:build go1.20 && !go1.21
2+
3+
package common
4+
5+
import "github.com/sagernet/sing/common/x/constraints"
6+
7+
func Min[T constraints.Ordered](x, y T) T {
8+
if x < y {
9+
return x
10+
}
11+
return y
12+
}
13+
14+
func Max[T constraints.Ordered](x, y T) T {
15+
if x < y {
16+
return y
17+
}
18+
return x
19+
}

common/oncefunc.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//go:build go1.21
2+
3+
package common
4+
5+
import "sync"
6+
7+
// OnceFunc is a wrapper around sync.OnceFunc.
8+
func OnceFunc(f func()) func() {
9+
return sync.OnceFunc(f)
10+
}
11+
12+
// OnceValue is a wrapper around sync.OnceValue.
13+
func OnceValue[T any](f func() T) func() T {
14+
return sync.OnceValue(f)
15+
}
16+
17+
// OnceValues is a wrapper around sync.OnceValues.
18+
func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) {
19+
return sync.OnceValues(f)
20+
}

common/oncefunc_compat.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build go1.20 && !go1.21
6+
7+
package common
8+
9+
import "sync"
10+
11+
// OnceFunc returns a function that invokes f only once. The returned function
12+
// may be called concurrently.
13+
//
14+
// If f panics, the returned function will panic with the same value on every call.
15+
func OnceFunc(f func()) func() {
16+
var (
17+
once sync.Once
18+
valid bool
19+
p any
20+
)
21+
// Construct the inner closure just once to reduce costs on the fast path.
22+
g := func() {
23+
defer func() {
24+
p = recover()
25+
if !valid {
26+
// Re-panic immediately so on the first call the user gets a
27+
// complete stack trace into f.
28+
panic(p)
29+
}
30+
}()
31+
f()
32+
f = nil // Do not keep f alive after invoking it.
33+
valid = true // Set only if f does not panic.
34+
}
35+
return func() {
36+
once.Do(g)
37+
if !valid {
38+
panic(p)
39+
}
40+
}
41+
}
42+
43+
// OnceValue returns a function that invokes f only once and returns the value
44+
// returned by f. The returned function may be called concurrently.
45+
//
46+
// If f panics, the returned function will panic with the same value on every call.
47+
func OnceValue[T any](f func() T) func() T {
48+
var (
49+
once sync.Once
50+
valid bool
51+
p any
52+
result T
53+
)
54+
g := func() {
55+
defer func() {
56+
p = recover()
57+
if !valid {
58+
panic(p)
59+
}
60+
}()
61+
result = f()
62+
f = nil
63+
valid = true
64+
}
65+
return func() T {
66+
once.Do(g)
67+
if !valid {
68+
panic(p)
69+
}
70+
return result
71+
}
72+
}
73+
74+
// OnceValues returns a function that invokes f only once and returns the values
75+
// returned by f. The returned function may be called concurrently.
76+
//
77+
// If f panics, the returned function will panic with the same value on every call.
78+
func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) {
79+
var (
80+
once sync.Once
81+
valid bool
82+
p any
83+
r1 T1
84+
r2 T2
85+
)
86+
g := func() {
87+
defer func() {
88+
p = recover()
89+
if !valid {
90+
panic(p)
91+
}
92+
}()
93+
r1, r2 = f()
94+
f = nil
95+
valid = true
96+
}
97+
return func() (T1, T2) {
98+
once.Do(g)
99+
if !valid {
100+
panic(p)
101+
}
102+
return r1, r2
103+
}
104+
}

0 commit comments

Comments
 (0)