value.go 963 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. package csync
  2. import (
  3. "reflect"
  4. "sync"
  5. )
  6. // Value is a generic thread-safe wrapper for any value type.
  7. //
  8. // For slices, use [Slice]. For maps, use [Map]. Pointers are not supported.
  9. type Value[T any] struct {
  10. v T
  11. mu sync.RWMutex
  12. }
  13. // NewValue creates a new Value with the given initial value.
  14. //
  15. // Panics if t is a pointer, slice, or map. Use the dedicated types for those.
  16. func NewValue[T any](t T) *Value[T] {
  17. v := reflect.ValueOf(t)
  18. switch v.Kind() {
  19. case reflect.Pointer:
  20. panic("csync.Value does not support pointer types")
  21. case reflect.Slice:
  22. panic("csync.Value does not support slice types; use csync.Slice")
  23. case reflect.Map:
  24. panic("csync.Value does not support map types; use csync.Map")
  25. }
  26. return &Value[T]{v: t}
  27. }
  28. // Get returns the current value.
  29. func (v *Value[T]) Get() T {
  30. v.mu.RLock()
  31. defer v.mu.RUnlock()
  32. return v.v
  33. }
  34. // Set updates the value.
  35. func (v *Value[T]) Set(t T) {
  36. v.mu.Lock()
  37. defer v.mu.Unlock()
  38. v.v = t
  39. }