list.mx raw

   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