From df5a5c3c089073be4709f37dad14be5e122e5e19 Mon Sep 17 00:00:00 2001 From: Prashant Varanasi Date: Fri, 11 Jun 2021 08:23:41 -0700 Subject: [PATCH] Add Swap for Float64 (#94) Float64 wraps a Uint64, and since Uint64 supports Swap, Float64 can also support Swap. Enable the Swap method in the generated code, and add tests. This also adds a note for why String doesn't support Swap (though it will be possible after Go 1.17+). --- CHANGELOG.md | 4 ++++ float64.go | 6 ++++++ float64_ext.go | 2 +- float64_test.go | 3 +++ string_ext.go | 2 ++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c3f238..fd57533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased +### Added +- Add `Float64.Swap` to match int atomic operations. + ## [1.8.0] - 2021-06-09 ### Added - Add `atomic.Uintptr` type for atomic operations on `uintptr` values. diff --git a/float64.go b/float64.go index cf6f670..3f38ef2 100644 --- a/float64.go +++ b/float64.go @@ -55,6 +55,12 @@ func (x *Float64) Store(v float64) { x.v.Store(math.Float64bits(v)) } +// Swap atomically stores the given float64 and returns the old +// value. +func (x *Float64) Swap(o float64) float64 { + return math.Float64frombits(x.v.Swap(math.Float64bits(o))) +} + // MarshalJSON encodes the wrapped float64 into JSON. func (x *Float64) MarshalJSON() ([]byte, error) { return json.Marshal(x.Load()) diff --git a/float64_ext.go b/float64_ext.go index 1a7476a..8a4ca8f 100644 --- a/float64_ext.go +++ b/float64_ext.go @@ -25,7 +25,7 @@ import ( "strconv" ) -//go:generate bin/gen-atomicwrapper -name=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -json -imports math -file=float64.go +//go:generate bin/gen-atomicwrapper -name=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -swap -json -imports math -file=float64.go // Add atomically adds to the wrapped float64 and returns the new value. func (f *Float64) Add(s float64) float64 { diff --git a/float64_test.go b/float64_test.go index bc04e77..d334de9 100644 --- a/float64_test.go +++ b/float64_test.go @@ -42,6 +42,9 @@ func TestFloat64(t *testing.T) { require.Equal(t, float64(42.5), atom.Add(0.5), "Add didn't work.") require.Equal(t, float64(42.0), atom.Sub(0.5), "Sub didn't work.") + require.Equal(t, float64(42.0), atom.Swap(45.0), "Swap didn't return the old value.") + require.Equal(t, float64(45.0), atom.Load(), "Swap didn't set the correct value.") + t.Run("JSON/Marshal", func(t *testing.T) { atom.Store(42.5) bytes, err := json.Marshal(atom) diff --git a/string_ext.go b/string_ext.go index 3a95582..83d92ed 100644 --- a/string_ext.go +++ b/string_ext.go @@ -21,6 +21,8 @@ package atomic //go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped=Value -file=string.go +// Note: No Swap as String wraps Value, which wraps the stdlib sync/atomic.Value which +// only supports Swap as of go1.17: https://github.com/golang/go/issues/39351 // String returns the wrapped value. func (s *String) String() string {