diff --git a/union/union.go b/union/union.go index a448fa9..5379ba8 100644 --- a/union/union.go +++ b/union/union.go @@ -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 } }