github.com/hslam/atomic@v1.0.0/float32.go (about)

     1  // Copyright (c) 2020 Meng Huang (mhboy@outlook.com)
     2  // This package is licensed under a MIT license that can be found in the LICENSE file.
     3  
     4  package atomic
     5  
     6  import (
     7  	"sync/atomic"
     8  	"unsafe"
     9  )
    10  
    11  // Float32 represents an float32.
    12  type Float32 struct {
    13  	v uint32
    14  }
    15  
    16  // NewFloat32 returns a new Float32.
    17  func NewFloat32(val float32) *Float32 {
    18  	addr := &Float32{}
    19  	addr.Store(val)
    20  	return addr
    21  }
    22  
    23  // Swap atomically stores new into *addr and returns the previous *addr value.
    24  func (addr *Float32) Swap(new float32) (old float32) {
    25  	var v = atomic.SwapUint32(&addr.v, *(*uint32)(unsafe.Pointer(&new)))
    26  	return *(*float32)(unsafe.Pointer(&v))
    27  }
    28  
    29  // CompareAndSwap executes the compare-and-swap operation for an float32 value.
    30  func (addr *Float32) CompareAndSwap(old, new float32) (swapped bool) {
    31  	return atomic.CompareAndSwapUint32(&addr.v, *(*uint32)(unsafe.Pointer(&old)), *(*uint32)(unsafe.Pointer(&new)))
    32  }
    33  
    34  // Add atomically adds delta to *addr and returns the new value.
    35  func (addr *Float32) Add(delta float32) (new float32) {
    36  	for {
    37  		old := addr.Load()
    38  		new = old + delta
    39  		if addr.CompareAndSwap(old, new) {
    40  			return
    41  		}
    42  	}
    43  }
    44  
    45  // Load atomically loads *addr.
    46  func (addr *Float32) Load() (val float32) {
    47  	var v = atomic.LoadUint32(&addr.v)
    48  	return *(*float32)(unsafe.Pointer(&v))
    49  }
    50  
    51  // Store atomically stores val into *addr.
    52  func (addr *Float32) Store(val float32) {
    53  	atomic.StoreUint32(&addr.v, *(*uint32)(unsafe.Pointer(&val)))
    54  }