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}