github.com/anacrolix/torrent@v1.61.0/atomic-count.go (about) 1 package torrent 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "reflect" 7 "sync/atomic" 8 ) 9 10 type Count struct { 11 n int64 12 } 13 14 var _ fmt.Stringer = (*Count)(nil) 15 16 func (me *Count) Add(n int64) { 17 atomic.AddInt64(&me.n, n) 18 } 19 20 func (me *Count) Int64() int64 { 21 return atomic.LoadInt64(&me.n) 22 } 23 24 func (me *Count) String() string { 25 return fmt.Sprintf("%v", me.Int64()) 26 } 27 28 func (me *Count) MarshalJSON() ([]byte, error) { 29 return json.Marshal(me.n) 30 } 31 32 // TODO: Can this use more generics to speed it up? Should we be checking the field types? 33 func copyCountFields[T any](src *T) (dst T) { 34 srcValue := reflect.ValueOf(src).Elem() 35 dstValue := reflect.ValueOf(&dst).Elem() 36 for i := 0; i < reflect.TypeFor[T]().NumField(); i++ { 37 n := srcValue.Field(i).Addr().Interface().(*Count).Int64() 38 dstValue.Field(i).Addr().Interface().(*Count).Add(n) 39 } 40 return 41 }