todo: fix unions or remove them
This commit is contained in:
parent
4722e6a61f
commit
41b74c5b14
1 changed files with 12 additions and 26 deletions
|
|
@ -36,7 +36,7 @@ type anystruct any
|
|||
// float32
|
||||
// })
|
||||
type Of[T anystruct] struct {
|
||||
typ reflect.Kind
|
||||
typ reflect.Type
|
||||
mem []byte
|
||||
}
|
||||
|
||||
|
|
@ -47,39 +47,25 @@ func (u Of[T]) Size() uintptr {
|
|||
// String returns the string representation of a union.
|
||||
func (u Of[T]) String() string {
|
||||
var b strings.Builder
|
||||
b.WriteString("union[")
|
||||
if u.typ == reflect.Invalid {
|
||||
|
||||
fmt.Fprintf(&b, "union[%s] = ", reflect.TypeFor[T]().String())
|
||||
if u.typ == nil {
|
||||
b.WriteString("none")
|
||||
} else {
|
||||
b.WriteString(u.typ.String())
|
||||
}
|
||||
b.WriteString("] {")
|
||||
|
||||
t := reflect.TypeFor[T]()
|
||||
if t.Kind() == reflect.Struct {
|
||||
b.WriteByte(' ')
|
||||
fields := getInternalFields(u)
|
||||
for i, field := range fields {
|
||||
b.WriteString(field.Type.String())
|
||||
if i < len(fields)-1 {
|
||||
b.WriteString("; ")
|
||||
}
|
||||
}
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
|
||||
b.WriteByte('}')
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Is returns true if the given type is currently stored in the union.
|
||||
func Is[E any, T anystruct](u Of[T]) bool {
|
||||
// Explicit invalid check to make sure invalid types don't result in false-positives.
|
||||
if u.typ == reflect.Invalid {
|
||||
if u.typ == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return u.typ == reflect.TypeFor[E]().Kind()
|
||||
return u.typ == reflect.TypeFor[E]()
|
||||
}
|
||||
|
||||
// Set overwrites the backing memory of a union with the given value; initializing the union if uninitialized.
|
||||
|
|
@ -91,8 +77,8 @@ func Set[V any, T anystruct](u *Of[T], value V) {
|
|||
u.mem = make([]byte, mem.Sizeof[T]())
|
||||
}
|
||||
|
||||
*(*V)(unsafe.Pointer(&u.mem[0])) = value
|
||||
u.typ = reflect.TypeFor[V]().Kind()
|
||||
unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0] = value
|
||||
u.typ = reflect.TypeFor[V]()
|
||||
}
|
||||
|
||||
// SetSafe overwrites the backing memory of a union with the given value,
|
||||
|
|
@ -107,8 +93,8 @@ func SetSafe[V any, T anystruct](u *Of[T], value V) error {
|
|||
vt := reflect.TypeFor[V]()
|
||||
for _, field := range getInternalFields(*u) {
|
||||
if field.Type == vt {
|
||||
*(*V)(unsafe.Pointer(&u.mem[0])) = value
|
||||
u.typ = reflect.TypeFor[V]().Kind()
|
||||
unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0] = value
|
||||
u.typ = reflect.TypeFor[V]()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
@ -125,7 +111,7 @@ func Get[V any, T anystruct](u Of[T]) V {
|
|||
panic(ErrUninitializedAccess)
|
||||
}
|
||||
|
||||
return *(*V)(unsafe.Pointer(&u.mem[0]))
|
||||
return unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0]
|
||||
}
|
||||
|
||||
// GetSafe returns the union's backing memory interpreted as a value of type V, returning an error if the type
|
||||
|
|
@ -140,7 +126,7 @@ func GetSafe[V any, T anystruct](u Of[T]) (V, error) {
|
|||
vt := reflect.TypeFor[V]()
|
||||
for _, field := range getInternalFields(u) {
|
||||
if field.Type == vt {
|
||||
return *(*V)(unsafe.Pointer(&u.mem[0])), nil
|
||||
return unsafe.Slice((*V)(unsafe.Pointer(&u.mem[0])), 1)[0], nil
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue