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))) }