github.com/haraldrudell/parl@v0.4.176/atomic-32.go (about) 1 /* 2 © 2023-present Harald Rudell <haraldrudell@proton.me> (https://haraldrudell.github.io/haraldrudell/) 3 All rights reserved 4 */ 5 6 package parl 7 8 import ( 9 "sync/atomic" 10 11 "golang.org/x/exp/constraints" 12 ) 13 14 // the integer types supported by Atomic32 15 // - does not include ~uint64 ~uintptr ~int64 16 type uint32Types interface { 17 ~int | ~int8 | ~int16 | ~int32 | 18 ~uint | ~uint8 | ~uint16 | ~uint32 19 } 20 21 type _[T constraints.Unsigned | constraints.Signed] int 22 23 var _ atomic.Uint32 24 25 // Atomic32 is a generic 32-bit integer with atomic access 26 // - generic for named types of select signed and unsigned underlying integers 27 // - generic for select built-in integer types 28 // - includes ~int ~uint 29 // - excludes ~uint64 ~uintptr ~int64 30 // - for large values or excluded types, use [Atomic64] 31 // - generic version of [atomic.Uint32] 32 // - when using int or uint underlying type on a 64-bit platform, 33 // type-conversion data loss may occur for larger than 32-bit values 34 // - no performance impact compared to other atomics 35 type Atomic32[T uint32Types] struct { 36 _ noCopy 37 v uint32 38 } 39 40 // Load atomically loads and returns the value stored in a. 41 func (a *Atomic32[T]) Load() (value T) { return T(atomic.LoadUint32(&a.v)) } 42 43 // Store atomically stores val into a. 44 func (a *Atomic32[T]) Store(val T) { atomic.StoreUint32(&a.v, uint32(val)) } 45 46 // Swap atomically stores new into a and returns the previous value. 47 func (a *Atomic32[T]) Swap(new T) (old T) { return T(atomic.SwapUint32(&a.v, uint32(new))) } 48 49 // CompareAndSwap executes the compare-and-swap operation for a. 50 func (a *Atomic32[T]) CompareAndSwap(old, new T) (swapped bool) { 51 return atomic.CompareAndSwapUint32(&a.v, uint32(old), uint32(new)) 52 } 53 54 // Add atomically adds delta to a and returns the new value. 55 func (a *Atomic32[T]) Add(delta T) (new T) { return T(atomic.AddUint32(&a.v, uint32(delta))) }