summaryrefslogtreecommitdiffstats
path: root/pkg/com/atomic.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:36:04 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:36:04 +0000
commitb09c6d56832eb1718c07d74abf3bc6ae3fe4e030 (patch)
treed2caec2610d4ea887803ec9e9c3cd77136c448ba /pkg/com/atomic.go
parentInitial commit. (diff)
downloadicingadb-upstream.tar.xz
icingadb-upstream.zip
Adding upstream version 1.1.0.upstream/1.1.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--pkg/com/atomic.go38
1 files changed, 38 insertions, 0 deletions
diff --git a/pkg/com/atomic.go b/pkg/com/atomic.go
new file mode 100644
index 0000000..316413d
--- /dev/null
+++ b/pkg/com/atomic.go
@@ -0,0 +1,38 @@
+package com
+
+import "sync/atomic"
+
+// Atomic is a type-safe wrapper around atomic.Value.
+type Atomic[T any] struct {
+ v atomic.Value
+}
+
+func (a *Atomic[T]) Load() (_ T, ok bool) {
+ if v, ok := a.v.Load().(box[T]); ok {
+ return v.v, true
+ }
+
+ return
+}
+
+func (a *Atomic[T]) Store(v T) {
+ a.v.Store(box[T]{v})
+}
+
+func (a *Atomic[T]) Swap(new T) (old T, ok bool) {
+ if old, ok := a.v.Swap(box[T]{new}).(box[T]); ok {
+ return old.v, true
+ }
+
+ return
+}
+
+func (a *Atomic[T]) CompareAndSwap(old, new T) (swapped bool) {
+ return a.v.CompareAndSwap(box[T]{old}, box[T]{new})
+}
+
+// box allows, for the case T is an interface, nil values and values of different specific types implementing T
+// to be stored in Atomic[T]#v (bypassing atomic.Value#Store()'s policy) by wrapping it (into a non-interface).
+type box[T any] struct {
+ v T
+}