1package sentinel
 2
 3import (
 4	"github.com/anthropics/anthropic-sdk-go/internal/encoding/json/shims"
 5	"reflect"
 6	"sync"
 7)
 8
 9var nullPtrsCache sync.Map // map[reflect.Type]*T
10
11func NullPtr[T any]() *T {
12	t := shims.TypeFor[T]()
13	ptr, loaded := nullPtrsCache.Load(t) // avoid premature allocation
14	if !loaded {
15		ptr, _ = nullPtrsCache.LoadOrStore(t, new(T))
16	}
17	return (ptr.(*T))
18}
19
20var nullSlicesCache sync.Map // map[reflect.Type][]T
21
22func NullSlice[T any]() []T {
23	t := shims.TypeFor[T]()
24	slice, loaded := nullSlicesCache.Load(t) // avoid premature allocation
25	if !loaded {
26		slice, _ = nullSlicesCache.LoadOrStore(t, []T{})
27	}
28	return slice.([]T)
29}
30
31func IsNullPtr[T any](ptr *T) bool {
32	nullptr, ok := nullPtrsCache.Load(shims.TypeFor[T]())
33	return ok && ptr == nullptr.(*T)
34}
35
36func IsNullSlice[T any](slice []T) bool {
37	nullSlice, ok := nullSlicesCache.Load(shims.TypeFor[T]())
38	return ok && reflect.ValueOf(slice).Pointer() == reflect.ValueOf(nullSlice).Pointer()
39}
40
41// internal only
42func IsValueNullPtr(v reflect.Value) bool {
43	if v.Kind() != reflect.Ptr {
44		return false
45	}
46	nullptr, ok := nullPtrsCache.Load(v.Type().Elem())
47	return ok && v.Pointer() == reflect.ValueOf(nullptr).Pointer()
48}
49
50// internal only
51func IsValueNullSlice(v reflect.Value) bool {
52	if v.Kind() != reflect.Slice {
53		return false
54	}
55	nullSlice, ok := nullSlicesCache.Load(v.Type().Elem())
56	return ok && v.Pointer() == reflect.ValueOf(nullSlice).Pointer()
57}