From e63519f6ead569348d4203ec2db353ff878d57eb Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Thu, 14 May 2020 16:18:15 -0700 Subject: [PATCH] float64: Generate with gen-atomicwrapper Generate atomic.Float64 with gen-valuewrapper by wrapping atomic.Uint64, using math.Float64bits and math.Float64frombits to pack and unpack float64 to uint64. --- float64.go | 68 +++++++++++++++++++------------------------------- float64_ext.go | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 42 deletions(-) create mode 100644 float64_ext.go diff --git a/float64.go b/float64.go index fd9e250..fb33e90 100644 --- a/float64.go +++ b/float64.go @@ -1,3 +1,5 @@ +// @generated Code generated by gen-atomicwrapper. + // Copyright (c) 2020 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy @@ -23,70 +25,52 @@ package atomic import ( "encoding/json" "math" - "strconv" - "sync/atomic" ) -// Float64 is an atomic wrapper around float64. +// Float64 is an atomic type-safe wrapper for float64 values. type Float64 struct { nocmp // disallow non-atomic comparison - v uint64 -} - -// NewFloat64 creates a Float64. -func NewFloat64(f float64) *Float64 { - return &Float64{v: math.Float64bits(f)} + v Uint64 } -// Load atomically loads the wrapped value. -func (f *Float64) Load() float64 { - return math.Float64frombits(atomic.LoadUint64(&f.v)) -} +var _zeroFloat64 float64 -// Store atomically stores the passed value. -func (f *Float64) Store(s float64) { - atomic.StoreUint64(&f.v, math.Float64bits(s)) +// NewFloat64 creates a new Float64. +func NewFloat64(v float64) *Float64 { + x := &Float64{} + if v != _zeroFloat64 { + x.Store(v) + } + return x } -// Add atomically adds to the wrapped float64 and returns the new value. -func (f *Float64) Add(s float64) float64 { - for { - old := f.Load() - new := old + s - if f.CAS(old, new) { - return new - } - } +// Load atomically loads the wrapped float64. +func (x *Float64) Load() float64 { + return math.Float64frombits(x.v.Load()) } -// Sub atomically subtracts from the wrapped float64 and returns the new value. -func (f *Float64) Sub(s float64) float64 { - return f.Add(-s) +// Store atomically stores the passed float64. +func (x *Float64) Store(v float64) { + x.v.Store(math.Float64bits(v)) } -// CAS is an atomic compare-and-swap. -func (f *Float64) CAS(old, new float64) bool { - return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new)) +// CAS is an atomic compare-and-swap for float64 values. +func (x *Float64) CAS(o, n float64) bool { + return x.v.CAS(math.Float64bits(o), math.Float64bits(n)) } // MarshalJSON encodes the wrapped float64 into JSON. -func (f *Float64) MarshalJSON() ([]byte, error) { - return json.Marshal(f.Load()) +func (x *Float64) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) } -// UnmarshalJSON decodes JSON into the wrapped float64. -func (f *Float64) UnmarshalJSON(b []byte) error { +// UnmarshalJSON decodes a float64 from JSON. +func (x *Float64) UnmarshalJSON(b []byte) error { var v float64 if err := json.Unmarshal(b, &v); err != nil { return err } - f.Store(v) + x.Store(v) return nil } - -// String encodes the wrapped value as a string. -func (f *Float64) String() string { - // 'g' is the behavior for floats with %v. - return strconv.FormatFloat(f.Load(), 'g', -1, 64) -} diff --git a/float64_ext.go b/float64_ext.go new file mode 100644 index 0000000..927b1ad --- /dev/null +++ b/float64_ext.go @@ -0,0 +1,47 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import "strconv" + +//go:generate bin/gen-atomicwrapper -name=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -cas -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 { + for { + old := f.Load() + new := old + s + if f.CAS(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped float64 and returns the new value. +func (f *Float64) Sub(s float64) float64 { + return f.Add(-s) +} + +// String encodes the wrapped value as a string. +func (f *Float64) String() string { + // 'g' is the behavior for floats with %v. + return strconv.FormatFloat(f.Load(), 'g', -1, 64) +}