github.com/anthropics/anthropic-sdk-go@v1.70.1/internal/encoding/json/sentinel/null.go (about)

     1  package sentinel
     2  
     3  import (
     4  	"github.com/anthropics/anthropic-sdk-go/internal/encoding/json/shims"
     5  	"reflect"
     6  	"sync"
     7  )
     8  
     9  type cacheEntry struct {
    10  	x    any
    11  	ptr  uintptr
    12  	kind reflect.Kind
    13  }
    14  
    15  var nullCache sync.Map // map[reflect.Type]cacheEntry
    16  
    17  func NewNullSentinel[T any](mk func() T) T {
    18  	t := shims.TypeFor[T]()
    19  	entry, loaded := nullCache.Load(t) // avoid premature allocation
    20  	if !loaded {
    21  		x := mk()
    22  		ptr := reflect.ValueOf(x).Pointer()
    23  		entry, _ = nullCache.LoadOrStore(t, cacheEntry{x, ptr, t.Kind()})
    24  	}
    25  	return entry.(cacheEntry).x.(T)
    26  }
    27  
    28  // for internal use only
    29  func IsValueNull(v reflect.Value) bool {
    30  	switch v.Kind() {
    31  	case reflect.Map, reflect.Slice:
    32  		null, ok := nullCache.Load(v.Type())
    33  		return ok && v.Pointer() == null.(cacheEntry).ptr
    34  	}
    35  	return false
    36  }
    37  
    38  func IsNull[T any](v T) bool {
    39  	t := shims.TypeFor[T]()
    40  	switch t.Kind() {
    41  	case reflect.Map, reflect.Slice:
    42  		null, ok := nullCache.Load(t)
    43  		return ok && reflect.ValueOf(v).Pointer() == null.(cacheEntry).ptr
    44  	}
    45  	return false
    46  }