wrapper.tmpl raw

   1  // Copyright (c) 2020-{{.ToYear}} Uber Technologies, Inc.
   2  //
   3  // Permission is hereby granted, free of charge, to any person obtaining a copy
   4  // of this software and associated documentation files (the "Software"), to deal
   5  // in the Software without restriction, including without limitation the rights
   6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   7  // copies of the Software, and to permit persons to whom the Software is
   8  // furnished to do so, subject to the following conditions:
   9  //
  10  // The above copyright notice and this permission notice shall be included in
  11  // all copies or substantial portions of the Software.
  12  //
  13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19  // THE SOFTWARE.
  20  
  21  package atomic
  22  
  23  import (
  24  	"encoding/json"
  25  	"strconv"
  26  	"sync/atomic"
  27  )
  28  
  29  // {{ .Name }} is an atomic wrapper around {{ .Wrapped }}.
  30  type {{ .Name }} struct {
  31  	_ nocmp // disallow non-atomic comparison
  32  
  33  	v {{ .Wrapped }}
  34  }
  35  
  36  // New{{ .Name }} creates a new {{ .Name }}.
  37  func New{{ .Name }}(val {{ .Wrapped }}) *{{ .Name }} {
  38  	return &{{ .Name }}{v: val}
  39  }
  40  
  41  // Load atomically loads the wrapped value.
  42  func (i *{{ .Name }}) Load() {{ .Wrapped }} {
  43  	return atomic.Load{{ .Name }}(&i.v)
  44  }
  45  
  46  // Add atomically adds to the wrapped {{ .Wrapped }} and returns the new value.
  47  func (i *{{ .Name }}) Add(delta {{ .Wrapped }}) {{ .Wrapped }} {
  48  	return atomic.Add{{ .Name }}(&i.v, delta)
  49  }
  50  
  51  // Sub atomically subtracts from the wrapped {{ .Wrapped }} and returns the new value.
  52  func (i *{{ .Name }}) Sub(delta {{ .Wrapped }}) {{ .Wrapped }} {
  53  	return atomic.Add{{ .Name }}(&i.v,
  54  		{{- if .Unsigned -}}
  55  			^(delta - 1)
  56  		{{- else -}}
  57  			-delta
  58  		{{- end -}}
  59  	)
  60  }
  61  
  62  // Inc atomically increments the wrapped {{ .Wrapped }} and returns the new value.
  63  func (i *{{ .Name }}) Inc() {{ .Wrapped }} {
  64  	return i.Add(1)
  65  }
  66  
  67  // Dec atomically decrements the wrapped {{ .Wrapped }} and returns the new value.
  68  func (i *{{ .Name }}) Dec() {{ .Wrapped }} {
  69  	return i.Sub(1)
  70  }
  71  
  72  // CAS is an atomic compare-and-swap.
  73  //
  74  // Deprecated: Use CompareAndSwap.
  75  func (i *{{ .Name }}) CAS(old, new {{ .Wrapped }}) (swapped bool) {
  76  	return i.CompareAndSwap(old, new)
  77  }
  78  
  79  // CompareAndSwap is an atomic compare-and-swap.
  80  func (i *{{ .Name }}) CompareAndSwap(old, new {{ .Wrapped }}) (swapped bool) {
  81  	return atomic.CompareAndSwap{{ .Name }}(&i.v, old, new)
  82  }
  83  
  84  // Store atomically stores the passed value.
  85  func (i *{{ .Name }}) Store(val {{ .Wrapped }}) {
  86  	atomic.Store{{ .Name }}(&i.v, val)
  87  }
  88  
  89  // Swap atomically swaps the wrapped {{ .Wrapped }} and returns the old value.
  90  func (i *{{ .Name }}) Swap(val {{ .Wrapped }}) (old {{ .Wrapped }}) {
  91  	return atomic.Swap{{ .Name }}(&i.v, val)
  92  }
  93  
  94  // MarshalJSON encodes the wrapped {{ .Wrapped }} into JSON.
  95  func (i *{{ .Name }}) MarshalJSON() (by, er) {
  96  	return json.Marshal(i.Load())
  97  }
  98  
  99  // UnmarshalJSON decodes JSON into the wrapped {{ .Wrapped }}.
 100  func (i *{{ .Name }}) UnmarshalJSON(b by) er {
 101  	var v {{ .Wrapped }}
 102  	if err := json.Unmarshal(b, &v); err != nil {
 103  		return err
 104  	}
 105  	i.Store(v)
 106  	return nil
 107  }
 108  
 109  // String encodes the wrapped value as a string.
 110  func (i *{{ .Name }}) String() string {
 111  	v := i.Load()
 112  	{{ if .Unsigned -}}
 113  		return strconv.FormatUint(uint64(v), 10)
 114  	{{- else -}}
 115  		return strconv.FormatInt(int64(v), 10)
 116  	{{- end }}
 117  }
 118