1 package cm
2 3 import (
4 "unsafe"
5 )
6 7 // List represents a Component Model list.
8 // The binary representation of list<T> is similar to a Go slice minus the cap field.
9 type List[T any] struct {
10 _ HostLayout
11 list[T]
12 }
13 14 // AnyList is a type constraint for generic functions that accept any [List] type.
15 type AnyList[T any] interface {
16 ~struct {
17 _ HostLayout
18 list[T]
19 }
20 }
21 22 // NewList returns a List[T] from data and len.
23 func NewList[T any, Len AnyInteger](data *T, len Len) List[T] {
24 return List[T]{
25 list: list[T]{
26 data: data,
27 len: uintptr(len),
28 },
29 }
30 }
31 32 // ToList returns a List[T] equivalent to the Go slice s.
33 // The underlying slice data is not copied, and the resulting List points at the
34 // same array storage as the slice.
35 func ToList[S ~[]T, T any](s S) List[T] {
36 return NewList[T](unsafe.SliceData([]T(s)), uintptr(len(s)))
37 }
38 39 // list represents the internal representation of a Component Model list.
40 // It is intended to be embedded in a [List], so embedding types maintain
41 // the methods defined on this type.
42 type list[T any] struct {
43 _ HostLayout
44 data *T
45 len uintptr
46 }
47 48 // Slice returns a Go slice representing the List.
49 func (l list[T]) Slice() []T {
50 return unsafe.Slice(l.data, l.len)
51 }
52 53 // Data returns the data pointer for the list.
54 func (l list[T]) Data() *T {
55 return l.data
56 }
57 58 // Len returns the length of the list.
59 // TODO: should this return an int instead of a uintptr?
60 func (l list[T]) Len() uintptr {
61 return l.len
62 }
63