value.go

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