diff --git a/Makefile b/Makefile index 46c945b..5679586 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ export GOBIN ?= $(shell pwd)/bin GOLINT = $(GOBIN)/golint GEN_ATOMICINT = $(GOBIN)/gen-atomicint GEN_ATOMICWRAPPER = $(GOBIN)/gen-atomicwrapper +GEN_ATOMICWRAPPER_GO119 = $(GOBIN)/gen-atomicwrapper-go119 STATICCHECK = $(GOBIN)/staticcheck GO_FILES ?= $(shell find . '(' -path .git -o -path vendor ')' -prune -o -name '*.go' -print) @@ -11,7 +12,8 @@ GO_FILES ?= $(shell find . '(' -path .git -o -path vendor ')' -prune -o -name '* # Also update ignore section in .codecov.yml. COVER_IGNORE_PKGS = \ go.uber.org/atomic/internal/gen-atomicint \ - go.uber.org/atomic/internal/gen-atomicwrapper + go.uber.org/atomic/internal/gen-atomicwrapper \ + go.uber.org/atomic/internal/gen-atomicwrapper-go119 .PHONY: build build: @@ -36,6 +38,9 @@ $(STATICCHECK): $(GEN_ATOMICWRAPPER): $(wildcard ./internal/gen-atomicwrapper/*) go build -o $@ ./internal/gen-atomicwrapper +$(GEN_ATOMICINT_GO119): $(wildcard ./internal/gen-atomicwrapper-go119/*) + go build -o $@ ./internal/gen-atomicwrapper-go119 + $(GEN_ATOMICINT): $(wildcard ./internal/gen-atomicint/*) go build -o $@ ./internal/gen-atomicint @@ -62,7 +67,7 @@ cover: go tool cover -html=cover.out -o cover.html .PHONY: generate -generate: $(GEN_ATOMICINT) $(GEN_ATOMICWRAPPER) +generate: $(GEN_ATOMICINT) $(GEN_ATOMICINT_GO119) $(GEN_ATOMICWRAPPER) go generate ./... .PHONY: generatenodirty diff --git a/gen.go b/gen.go index 1e9ef4f..54ba946 100644 --- a/gen.go +++ b/gen.go @@ -25,3 +25,8 @@ package atomic //go:generate bin/gen-atomicint -name=Uint32 -wrapped=uint32 -unsigned -file=uint32.go //go:generate bin/gen-atomicint -name=Uint64 -wrapped=uint64 -unsigned -file=uint64.go //go:generate bin/gen-atomicint -name=Uintptr -wrapped=uintptr -unsigned -file=uintptr.go +//go:generate bin/gen-atomicint-go119 -name=Int32 -wrapped=int32 -file=int32_go119.go +//go:generate bin/gen-atomicint-go119 -name=Int64 -wrapped=int64 -file=int64_go119.go +//go:generate bin/gen-atomicint-go119 -name=Uint32 -wrapped=uint32 -unsigned -file=uint32_go119.go +//go:generate bin/gen-atomicint-go119 -name=Uint64 -wrapped=uint64 -unsigned -file=uint64_go119.go +//go:generate bin/gen-atomicint-go119 -name=Uintptr -wrapped=uintptr -unsigned -file=uintptr_go119.go diff --git a/int32.go b/int32.go index b9a68f4..3c0c720 100644 --- a/int32.go +++ b/int32.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2022 Uber Technologies, Inc. +// Copyright (c) 2020-2023 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 @@ -20,6 +20,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +//go:build !go1.19 + package atomic import ( diff --git a/int32_go119.go b/int32_go119.go new file mode 100644 index 0000000..69eaefb --- /dev/null +++ b/int32_go119.go @@ -0,0 +1,113 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 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. + +//go:build go1.19 + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Int32 is an atomic wrapper around int32. +type Int32 struct { + _ nocmp // disallow non-atomic comparison + + v atomic.Int32 +} + +// NewInt32 creates a new Int32. +func NewInt32(val int32) *Int32 { + i := &Int32{} + i.Store(val) + return i +} + +// Load atomically loads the wrapped value. +func (i *Int32) Load() int32 { + return i.v.Load() +} + +// Add atomically adds to the wrapped int32 and returns the new value. +func (i *Int32) Add(delta int32) int32 { + return i.v.Add(delta) +} + +// Sub atomically subtracts from the wrapped int32 and returns the new value. +func (i *Int32) Sub(delta int32) int32 { + return i.v.Add(-delta) +} + +// Inc atomically increments the wrapped int32 and returns the new value. +func (i *Int32) Inc() int32 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped int32 and returns the new value. +func (i *Int32) Dec() int32 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Int32) CAS(old, new int32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int32) CompareAndSwap(old, new int32) (swapped bool) { + return i.v.CompareAndSwap(old, new) +} + +// Store atomically stores the passed value. +func (i *Int32) Store(val int32) { + i.v.Store(val) +} + +// Swap atomically swaps the wrapped int32 and returns the old value. +func (i *Int32) Swap(val int32) (old int32) { + return i.v.Swap(val) +} + +// MarshalJSON encodes the wrapped int32 into JSON. +func (i *Int32) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped int32. +func (i *Int32) UnmarshalJSON(b []byte) error { + var v int32 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Int32) String() string { + v := i.Load() + return strconv.FormatInt(int64(v), 10) +} diff --git a/int64.go b/int64.go index 78d2609..219a2af 100644 --- a/int64.go +++ b/int64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2022 Uber Technologies, Inc. +// Copyright (c) 2020-2023 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 @@ -20,6 +20,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +//go:build !go1.19 + package atomic import ( diff --git a/int64_go119.go b/int64_go119.go new file mode 100644 index 0000000..cb9ecdd --- /dev/null +++ b/int64_go119.go @@ -0,0 +1,113 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 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. + +//go:build go1.19 + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Int64 is an atomic wrapper around int64. +type Int64 struct { + _ nocmp // disallow non-atomic comparison + + v atomic.Int64 +} + +// NewInt64 creates a new Int64. +func NewInt64(val int64) *Int64 { + i := &Int64{} + i.Store(val) + return i +} + +// Load atomically loads the wrapped value. +func (i *Int64) Load() int64 { + return i.v.Load() +} + +// Add atomically adds to the wrapped int64 and returns the new value. +func (i *Int64) Add(delta int64) int64 { + return i.v.Add(delta) +} + +// Sub atomically subtracts from the wrapped int64 and returns the new value. +func (i *Int64) Sub(delta int64) int64 { + return i.v.Add(-delta) +} + +// Inc atomically increments the wrapped int64 and returns the new value. +func (i *Int64) Inc() int64 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped int64 and returns the new value. +func (i *Int64) Dec() int64 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Int64) CAS(old, new int64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int64) CompareAndSwap(old, new int64) (swapped bool) { + return i.v.CompareAndSwap(old, new) +} + +// Store atomically stores the passed value. +func (i *Int64) Store(val int64) { + i.v.Store(val) +} + +// Swap atomically swaps the wrapped int64 and returns the old value. +func (i *Int64) Swap(val int64) (old int64) { + return i.v.Swap(val) +} + +// MarshalJSON encodes the wrapped int64 into JSON. +func (i *Int64) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped int64. +func (i *Int64) UnmarshalJSON(b []byte) error { + var v int64 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Int64) String() string { + v := i.Load() + return strconv.FormatInt(int64(v), 10) +} diff --git a/internal/gen-atomicint-go119/main.go b/internal/gen-atomicint-go119/main.go new file mode 100644 index 0000000..a7cf3be --- /dev/null +++ b/internal/gen-atomicint-go119/main.go @@ -0,0 +1,116 @@ +// Copyright (c) 2020-2022 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. + +// gen-atomicint generates an atomic wrapper around an integer type. +// +// gen-atomicint -name Int32 -wrapped int32 -file out.go +// +// The generated wrapper will use the functions in the sync/atomic package +// named after the generated type. +package main + +import ( + "bytes" + "embed" + "errors" + "flag" + "fmt" + "go/format" + "io" + "log" + "os" + "text/template" + "time" +) + +func main() { + log.SetFlags(0) + if err := run(os.Args[1:]); err != nil { + log.Fatalf("%+v", err) + } +} + +func run(args []string) error { + var opts struct { + Name string + Wrapped string + File string + Unsigned bool + } + + flag := flag.NewFlagSet("gen-atomicint-go119", flag.ContinueOnError) + + flag.StringVar(&opts.Name, "name", "", "name of the generated type (e.g. Int32)") + flag.StringVar(&opts.Wrapped, "wrapped", "", "name of the wrapped type (e.g. int32)") + flag.StringVar(&opts.File, "file", "", "output file path (default: stdout)") + flag.BoolVar(&opts.Unsigned, "unsigned", false, "whether the type is unsigned") + + if err := flag.Parse(args); err != nil { + return err + } + + if len(opts.Name) == 0 || len(opts.Wrapped) == 0 { + return errors.New("flags -name and -wrapped are required") + } + + var w io.Writer = os.Stdout + if file := opts.File; len(file) > 0 { + f, err := os.Create(file) + if err != nil { + return fmt.Errorf("create %q: %v", file, err) + } + defer f.Close() + + w = f + } + + data := struct { + Name string + Wrapped string + Unsigned bool + ToYear int + }{ + Name: opts.Name, + Wrapped: opts.Wrapped, + Unsigned: opts.Unsigned, + ToYear: time.Now().Year(), + } + + var buff bytes.Buffer + if err := _tmpl.ExecuteTemplate(&buff, "wrapper.tmpl", data); err != nil { + return fmt.Errorf("render template: %v", err) + } + + bs, err := format.Source(buff.Bytes()) + if err != nil { + return fmt.Errorf("reformat source: %v", err) + } + + io.WriteString(w, "// @generated Code generated by gen-atomicint.\n\n") + _, err = w.Write(bs) + return err +} + +var ( + //go:embed *.tmpl + _tmplFS embed.FS + + _tmpl = template.Must(template.New("atomicint").ParseFS(_tmplFS, "*.tmpl")) +) diff --git a/internal/gen-atomicint-go119/wrapper.tmpl b/internal/gen-atomicint-go119/wrapper.tmpl new file mode 100644 index 0000000..7d2605e --- /dev/null +++ b/internal/gen-atomicint-go119/wrapper.tmpl @@ -0,0 +1,121 @@ +// Copyright (c) 2020-{{.ToYear}} 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. + +//go:build go1.19 + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// {{ .Name }} is an atomic wrapper around {{ .Wrapped }}. +type {{ .Name }} struct { + _ nocmp // disallow non-atomic comparison + + v atomic.{{ .Name }} +} + +// New{{ .Name }} creates a new {{ .Name }}. +func New{{ .Name }}(val {{ .Wrapped }}) *{{ .Name }} { + i := &{{ .Name }}{} + i.Store(val) + return i +} + +// Load atomically loads the wrapped value. +func (i *{{ .Name }}) Load() {{ .Wrapped }} { + return i.v.Load() +} + +// Add atomically adds to the wrapped {{ .Wrapped }} and returns the new value. +func (i *{{ .Name }}) Add(delta {{ .Wrapped }}) {{ .Wrapped }} { + return i.v.Add(delta) +} + +// Sub atomically subtracts from the wrapped {{ .Wrapped }} and returns the new value. +func (i *{{ .Name }}) Sub(delta {{ .Wrapped }}) {{ .Wrapped }} { + return i.v.Add( + {{- if .Unsigned -}} + ^(delta - 1) + {{- else -}} + -delta + {{- end -}} + ) +} + +// Inc atomically increments the wrapped {{ .Wrapped }} and returns the new value. +func (i *{{ .Name }}) Inc() {{ .Wrapped }} { + return i.Add(1) +} + +// Dec atomically decrements the wrapped {{ .Wrapped }} and returns the new value. +func (i *{{ .Name }}) Dec() {{ .Wrapped }} { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *{{ .Name }}) CAS(old, new {{ .Wrapped }}) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *{{ .Name }}) CompareAndSwap(old, new {{ .Wrapped }}) (swapped bool) { + return i.v.CompareAndSwap(old, new) +} + +// Store atomically stores the passed value. +func (i *{{ .Name }}) Store(val {{ .Wrapped }}) { + i.v.Store(val) +} + +// Swap atomically swaps the wrapped {{ .Wrapped }} and returns the old value. +func (i *{{ .Name }}) Swap(val {{ .Wrapped }}) (old {{ .Wrapped }}) { + return i.v.Swap(val) +} + +// MarshalJSON encodes the wrapped {{ .Wrapped }} into JSON. +func (i *{{ .Name }}) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped {{ .Wrapped }}. +func (i *{{ .Name }}) UnmarshalJSON(b []byte) error { + var v {{ .Wrapped }} + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *{{ .Name }}) String() string { + v := i.Load() + {{ if .Unsigned -}} + return strconv.FormatUint(uint64(v), 10) + {{- else -}} + return strconv.FormatInt(int64(v), 10) + {{- end }} +} diff --git a/internal/gen-atomicint/wrapper.tmpl b/internal/gen-atomicint/wrapper.tmpl index 51a0e3b..16a1607 100644 --- a/internal/gen-atomicint/wrapper.tmpl +++ b/internal/gen-atomicint/wrapper.tmpl @@ -18,6 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +//go:build !go1.19 + package atomic import ( diff --git a/uint32.go b/uint32.go index d6f04a9..e8b9165 100644 --- a/uint32.go +++ b/uint32.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2022 Uber Technologies, Inc. +// Copyright (c) 2020-2023 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 @@ -20,6 +20,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +//go:build !go1.19 + package atomic import ( diff --git a/uint32_go119.go b/uint32_go119.go new file mode 100644 index 0000000..4864fa9 --- /dev/null +++ b/uint32_go119.go @@ -0,0 +1,113 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 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. + +//go:build go1.19 + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Uint32 is an atomic wrapper around uint32. +type Uint32 struct { + _ nocmp // disallow non-atomic comparison + + v atomic.Uint32 +} + +// NewUint32 creates a new Uint32. +func NewUint32(val uint32) *Uint32 { + i := &Uint32{} + i.Store(val) + return i +} + +// Load atomically loads the wrapped value. +func (i *Uint32) Load() uint32 { + return i.v.Load() +} + +// Add atomically adds to the wrapped uint32 and returns the new value. +func (i *Uint32) Add(delta uint32) uint32 { + return i.v.Add(delta) +} + +// Sub atomically subtracts from the wrapped uint32 and returns the new value. +func (i *Uint32) Sub(delta uint32) uint32 { + return i.v.Add(^(delta - 1)) +} + +// Inc atomically increments the wrapped uint32 and returns the new value. +func (i *Uint32) Inc() uint32 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uint32 and returns the new value. +func (i *Uint32) Dec() uint32 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Uint32) CAS(old, new uint32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { + return i.v.CompareAndSwap(old, new) +} + +// Store atomically stores the passed value. +func (i *Uint32) Store(val uint32) { + i.v.Store(val) +} + +// Swap atomically swaps the wrapped uint32 and returns the old value. +func (i *Uint32) Swap(val uint32) (old uint32) { + return i.v.Swap(val) +} + +// MarshalJSON encodes the wrapped uint32 into JSON. +func (i *Uint32) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped uint32. +func (i *Uint32) UnmarshalJSON(b []byte) error { + var v uint32 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Uint32) String() string { + v := i.Load() + return strconv.FormatUint(uint64(v), 10) +} diff --git a/uint64.go b/uint64.go index 2574bdd..a839d11 100644 --- a/uint64.go +++ b/uint64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2022 Uber Technologies, Inc. +// Copyright (c) 2020-2023 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 @@ -20,6 +20,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +//go:build !go1.19 + package atomic import ( diff --git a/uint64_go119.go b/uint64_go119.go new file mode 100644 index 0000000..99f29c8 --- /dev/null +++ b/uint64_go119.go @@ -0,0 +1,113 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 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. + +//go:build go1.19 + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Uint64 is an atomic wrapper around uint64. +type Uint64 struct { + _ nocmp // disallow non-atomic comparison + + v atomic.Uint64 +} + +// NewUint64 creates a new Uint64. +func NewUint64(val uint64) *Uint64 { + i := &Uint64{} + i.Store(val) + return i +} + +// Load atomically loads the wrapped value. +func (i *Uint64) Load() uint64 { + return i.v.Load() +} + +// Add atomically adds to the wrapped uint64 and returns the new value. +func (i *Uint64) Add(delta uint64) uint64 { + return i.v.Add(delta) +} + +// Sub atomically subtracts from the wrapped uint64 and returns the new value. +func (i *Uint64) Sub(delta uint64) uint64 { + return i.v.Add(^(delta - 1)) +} + +// Inc atomically increments the wrapped uint64 and returns the new value. +func (i *Uint64) Inc() uint64 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uint64 and returns the new value. +func (i *Uint64) Dec() uint64 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Uint64) CAS(old, new uint64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { + return i.v.CompareAndSwap(old, new) +} + +// Store atomically stores the passed value. +func (i *Uint64) Store(val uint64) { + i.v.Store(val) +} + +// Swap atomically swaps the wrapped uint64 and returns the old value. +func (i *Uint64) Swap(val uint64) (old uint64) { + return i.v.Swap(val) +} + +// MarshalJSON encodes the wrapped uint64 into JSON. +func (i *Uint64) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped uint64. +func (i *Uint64) UnmarshalJSON(b []byte) error { + var v uint64 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Uint64) String() string { + v := i.Load() + return strconv.FormatUint(uint64(v), 10) +} diff --git a/uintptr.go b/uintptr.go index 81b275a..f97f99f 100644 --- a/uintptr.go +++ b/uintptr.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2022 Uber Technologies, Inc. +// Copyright (c) 2020-2023 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 @@ -20,6 +20,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +//go:build !go1.19 + package atomic import ( diff --git a/uintptr_go119.go b/uintptr_go119.go new file mode 100644 index 0000000..061386a --- /dev/null +++ b/uintptr_go119.go @@ -0,0 +1,113 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 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. + +//go:build go1.19 + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Uintptr is an atomic wrapper around uintptr. +type Uintptr struct { + _ nocmp // disallow non-atomic comparison + + v atomic.Uintptr +} + +// NewUintptr creates a new Uintptr. +func NewUintptr(val uintptr) *Uintptr { + i := &Uintptr{} + i.Store(val) + return i +} + +// Load atomically loads the wrapped value. +func (i *Uintptr) Load() uintptr { + return i.v.Load() +} + +// Add atomically adds to the wrapped uintptr and returns the new value. +func (i *Uintptr) Add(delta uintptr) uintptr { + return i.v.Add(delta) +} + +// Sub atomically subtracts from the wrapped uintptr and returns the new value. +func (i *Uintptr) Sub(delta uintptr) uintptr { + return i.v.Add(^(delta - 1)) +} + +// Inc atomically increments the wrapped uintptr and returns the new value. +func (i *Uintptr) Inc() uintptr { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uintptr and returns the new value. +func (i *Uintptr) Dec() uintptr { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Uintptr) CAS(old, new uintptr) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { + return i.v.CompareAndSwap(old, new) +} + +// Store atomically stores the passed value. +func (i *Uintptr) Store(val uintptr) { + i.v.Store(val) +} + +// Swap atomically swaps the wrapped uintptr and returns the old value. +func (i *Uintptr) Swap(val uintptr) (old uintptr) { + return i.v.Swap(val) +} + +// MarshalJSON encodes the wrapped uintptr into JSON. +func (i *Uintptr) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped uintptr. +func (i *Uintptr) UnmarshalJSON(b []byte) error { + var v uintptr + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Uintptr) String() string { + v := i.Load() + return strconv.FormatUint(uint64(v), 10) +}