blob: f888ae2bfa5e04cf45f5463e2d5d1dd23349a618 [file] [log] [blame]
go build main.go
! stdout .
! stderr .
-- main.go --
package main
import (
"p/b"
)
func main() {
f()
}
func f() {
typ := indexedPageType{newIndexedType(nil)}
page := newPage(typ.indexedType)
page.Data()
}
func newPage(typ *indexedType) Page {
values := typ.NewValues(nil, nil)
return &indexedPage{
typ: typ,
values: values.Int32(),
columnIndex: ^0,
}
}
type Type interface {
NewPage(columnIndex, numValues int, data b.Values) Page
NewValues(values []byte, offsets []uint32) b.Values
}
type Page interface {
Type() Type
Data() b.Values
}
type indexedPage struct {
typ *indexedType
values []int32
columnIndex int16
}
func (page *indexedPage) Type() Type { return indexedPageType{page.typ} }
func (page *indexedPage) Data() b.Values { return b.Int32Values(page.values) }
type indexedType struct {
Type
}
func newIndexedType(typ Type) *indexedType {
return &indexedType{Type: typ}
}
type indexedPageType struct{ *indexedType }
func (t indexedPageType) NewValues(values []byte, _ []uint32) b.Values {
return b.Int32ValuesFromBytes(values)
}
-- go.mod --
module p
go 1.24
-- internal/a/a.go --
package a
import "unsafe"
type slice struct {
ptr unsafe.Pointer
len int
cap int
}
func Slice[To, From any](data []From) []To {
// This function could use unsafe.Slice but it would drop the capacity
// information, so instead we implement the type conversion.
var zf From
var zt To
var s = slice{
ptr: unsafe.Pointer(unsafe.SliceData(data)),
len: int((uintptr(len(data)) * unsafe.Sizeof(zf)) / unsafe.Sizeof(zt)),
cap: int((uintptr(cap(data)) * unsafe.Sizeof(zf)) / unsafe.Sizeof(zt)),
}
return *(*[]To)(unsafe.Pointer(&s))
}
-- b/b.go --
package b
import "p/internal/a"
type Kind int32
const Int32 Kind = iota + 2
type Values struct {
kind Kind
size int32
data []byte
offsets []uint32
}
func (v *Values) Int32() []int32 {
return a.Slice[int32](v.data)
}
func makeValues[T any](kind Kind, values []T) Values {
return Values{kind: kind, data: a.Slice[byte](values)}
}
func Int32Values(values []int32) Values {
return makeValues(Int32, values)
}
func Int32ValuesFromBytes(values []byte) Values {
return Values{kind: Int32, data: values}
}