-
Notifications
You must be signed in to change notification settings - Fork 1
/
ptr.go
91 lines (81 loc) · 2.04 KB
/
ptr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package gg
/*
Takes an arbitrary value and returns a non-nil pointer to a new memory region
containing a shallow copy of that value.
*/
func Ptr[A any](val A) *A { return &val }
/*
If the pointer is nil, uses `new` to allocate a new value of the given type,
returning the resulting pointer. Otherwise returns the input as-is.
*/
func PtrInited[A any](val *A) *A {
if val != nil {
return val
}
return new(A)
}
/*
If the outer pointer is nil, returns nil. If the inner pointer is nil, uses
`new` to allocate a new value, sets and returns the resulting new pointer.
Otherwise returns the inner pointer as-is.
*/
func PtrInit[A any](val **A) *A {
if val == nil {
return nil
}
if *val == nil {
*val = new(A)
}
return *val
}
/*
Zeroes the memory referenced by the given pointer. If the pointer is nil, does
nothing. Also see the interface `Clearer` and method `.Clear` implemented by
various types.
Note the difference from built-in `clear` (Go 1.21+): when receiving a pointer
to a map or slice, this sets the target to `nil`, erasing the existing
capacity, while built-in `clear` would delete all map elements or zero all
slice elements (preserving length).
*/
func PtrClear[A any](val *A) {
if val != nil {
*val = Zero[A]()
}
}
// Calls `PtrClear` and returns the same pointer.
func PtrCleared[A any](val *A) *A {
PtrClear(val)
return val
}
// If the pointer is non-nil, dereferences it. Otherwise returns zero value.
func PtrGet[A any](val *A) A {
if val != nil {
return *val
}
return Zero[A]()
}
// If the pointer is nil, does nothing. If non-nil, set the given value.
func PtrSet[A any](tar *A, val A) {
if tar != nil {
*tar = val
}
}
/*
Takes two pointers and copies the value from source to target if both pointers
are non-nil. If either is nil, does nothing.
*/
func PtrSetOpt[A any](tar, src *A) {
if tar != nil && src != nil {
*tar = *src
}
}
/*
If the pointer is non-nil, returns its value while zeroing the destination.
Otherwise returns zero value.
*/
func PtrPop[A any](src *A) (out A) {
if src != nil {
out, *src = *src, out
}
return
}