package sparse

import (
	
	
)

type Array struct{ array }

func ( unsafe.Pointer,  int,  uintptr) Array {
	return Array{unsafeArray(, , )}
}

func ( Array) () int                   { return int(.len) }
func ( Array) ( int) unsafe.Pointer { return .index() }
func ( Array) (,  int) Array       { return Array{.slice(, )} }
func ( Array) ( uintptr) Array   { return Array{.offset()} }
func ( Array) () BoolArray       { return BoolArray{.array} }
func ( Array) () Int8Array       { return Int8Array{.array} }
func ( Array) () Int16Array     { return Int16Array{.array} }
func ( Array) () Int32Array     { return Int32Array{.array} }
func ( Array) () Int64Array     { return Int64Array{.array} }
func ( Array) () Float32Array { return Float32Array{.array} }
func ( Array) () Float64Array { return Float64Array{.array} }
func ( Array) () Uint8Array     { return Uint8Array{.array} }
func ( Array) () Uint16Array   { return Uint16Array{.array} }
func ( Array) () Uint32Array   { return Uint32Array{.array} }
func ( Array) () Uint64Array   { return Uint64Array{.array} }
func ( Array) () Uint128Array { return Uint128Array{.array} }
func ( Array) () StringArray   { return StringArray{.array} }
func ( Array) () TimeArray       { return TimeArray{.array} }

type array struct {
	ptr unsafe.Pointer
	len uintptr
	off uintptr
}

func makeArray[ any]( []) array {
	var  
	return array{
		ptr: unsafe.Pointer(unsafe.SliceData()),
		len: uintptr(len()),
		off: unsafe.Sizeof(),
	}
}

func unsafeArray( unsafe.Pointer,  int,  uintptr) array {
	return array{ptr: , len: uintptr(), off: }
}

func ( array) ( int) unsafe.Pointer {
	if uintptr() >= .len {
		panic("index out of bounds")
	}
	return unsafe.Add(.ptr, .off*uintptr())
}

func ( array) (,  int) array {
	if uintptr() > .len || uintptr() > .len ||  >  {
		panic("slice index out of bounds")
	}
	return array{
		ptr: unsafe.Add(.ptr, .off*uintptr()),
		len: uintptr( - ),
		off: .off,
	}
}

func ( array) ( uintptr) array {
	if .ptr == nil {
		panic("offset of nil array")
	}
	return array{
		ptr: unsafe.Add(.ptr, ),
		len: .len,
		off: .off,
	}
}

type BoolArray struct{ array }

func ( []bool) BoolArray {
	return BoolArray{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) BoolArray {
	return BoolArray{unsafeArray(, , )}
}

func ( BoolArray) () int                 { return int(.len) }
func ( BoolArray) ( int) bool         { return *(*byte)(.index()) != 0 }
func ( BoolArray) (,  int) BoolArray { return BoolArray{.slice(, )} }
func ( BoolArray) () Uint8Array   { return Uint8Array{.array} }
func ( BoolArray) () Array       { return Array{.array} }

type Int8Array struct{ array }

func ( []int8) Int8Array {
	return Int8Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Int8Array {
	return Int8Array{unsafeArray(, , )}
}

func ( Int8Array) () int                 { return int(.len) }
func ( Int8Array) ( int) int8         { return *(*int8)(.index()) }
func ( Int8Array) (,  int) Int8Array { return Int8Array{.slice(, )} }
func ( Int8Array) () Uint8Array   { return Uint8Array{.array} }
func ( Int8Array) () Array       { return Array{.array} }

type Int16Array struct{ array }

func ( []int16) Int16Array {
	return Int16Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Int16Array {
	return Int16Array{unsafeArray(, , )}
}

func ( Int16Array) () int                  { return int(.len) }
func ( Int16Array) ( int) int16         { return *(*int16)(.index()) }
func ( Int16Array) (,  int) Int16Array { return Int16Array{.slice(, )} }
func ( Int16Array) () Int8Array      { return Int8Array{.array} }
func ( Int16Array) () Uint8Array    { return Uint8Array{.array} }
func ( Int16Array) () Uint16Array  { return Uint16Array{.array} }
func ( Int16Array) () Array        { return Array{.array} }

type Int32Array struct{ array }

func ( []int32) Int32Array {
	return Int32Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Int32Array {
	return Int32Array{unsafeArray(, , )}
}

func ( Int32Array) () int                  { return int(.len) }
func ( Int32Array) ( int) int32         { return *(*int32)(.index()) }
func ( Int32Array) (,  int) Int32Array { return Int32Array{.slice(, )} }
func ( Int32Array) () Int8Array      { return Int8Array{.array} }
func ( Int32Array) () Int16Array    { return Int16Array{.array} }
func ( Int32Array) () Uint8Array    { return Uint8Array{.array} }
func ( Int32Array) () Uint16Array  { return Uint16Array{.array} }
func ( Int32Array) () Uint32Array  { return Uint32Array{.array} }
func ( Int32Array) () Array        { return Array{.array} }

type Int64Array struct{ array }

func ( []int64) Int64Array {
	return Int64Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Int64Array {
	return Int64Array{unsafeArray(, , )}
}

func ( Int64Array) () int                  { return int(.len) }
func ( Int64Array) ( int) int64         { return *(*int64)(.index()) }
func ( Int64Array) (,  int) Int64Array { return Int64Array{.slice(, )} }
func ( Int64Array) () Int8Array      { return Int8Array{.array} }
func ( Int64Array) () Int16Array    { return Int16Array{.array} }
func ( Int64Array) () Int32Array    { return Int32Array{.array} }
func ( Int64Array) () Uint8Array    { return Uint8Array{.array} }
func ( Int64Array) () Uint16Array  { return Uint16Array{.array} }
func ( Int64Array) () Uint32Array  { return Uint32Array{.array} }
func ( Int64Array) () Uint64Array  { return Uint64Array{.array} }
func ( Int64Array) () Array        { return Array{.array} }

type Float32Array struct{ array }

func ( []float32) Float32Array {
	return Float32Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Float32Array {
	return Float32Array{unsafeArray(, , )}
}

func ( Float32Array) () int                    { return int(.len) }
func ( Float32Array) ( int) float32         { return *(*float32)(.index()) }
func ( Float32Array) (,  int) Float32Array { return Float32Array{.slice(, )} }
func ( Float32Array) () Array                { return Array{.array} }
func ( Float32Array) () Uint32Array    { return Uint32Array{.array} }
func ( Float32Array) () Array          { return Array{.array} }

type Float64Array struct{ array }

func ( []float64) Float64Array {
	return Float64Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Float64Array {
	return Float64Array{unsafeArray(, , )}
}

func ( Float64Array) () int                    { return int(.len) }
func ( Float64Array) ( int) float64         { return *(*float64)(.index()) }
func ( Float64Array) (,  int) Float64Array { return Float64Array{.slice(, )} }
func ( Float64Array) () Uint64Array    { return Uint64Array{.array} }
func ( Float64Array) () Array          { return Array{.array} }

type Uint8Array struct{ array }

func ( []uint8) Uint8Array {
	return Uint8Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Uint8Array {
	return Uint8Array{unsafeArray(, , )}
}

func ( Uint8Array) () int                  { return int(.len) }
func ( Uint8Array) ( int) uint8         { return *(*uint8)(.index()) }
func ( Uint8Array) (,  int) Uint8Array { return Uint8Array{.slice(, )} }
func ( Uint8Array) () Array        { return Array{.array} }

type Uint16Array struct{ array }

func ( []uint16) Uint16Array {
	return Uint16Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Uint16Array {
	return Uint16Array{unsafeArray(, , )}
}

func ( Uint16Array) () int                   { return int(.len) }
func ( Uint16Array) ( int) uint16         { return *(*uint16)(.index()) }
func ( Uint16Array) (,  int) Uint16Array { return Uint16Array{.slice(, )} }
func ( Uint16Array) () Uint8Array     { return Uint8Array{.array} }
func ( Uint16Array) () Array         { return Array{.array} }

type Uint32Array struct{ array }

func ( []uint32) Uint32Array {
	return Uint32Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Uint32Array {
	return Uint32Array{unsafeArray(, , )}
}

func ( Uint32Array) () int                   { return int(.len) }
func ( Uint32Array) ( int) uint32         { return *(*uint32)(.index()) }
func ( Uint32Array) (,  int) Uint32Array { return Uint32Array{.slice(, )} }
func ( Uint32Array) () Uint8Array     { return Uint8Array{.array} }
func ( Uint32Array) () Uint16Array   { return Uint16Array{.array} }
func ( Uint32Array) () Array         { return Array{.array} }

type Uint64Array struct{ array }

func ( []uint64) Uint64Array {
	return Uint64Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Uint64Array {
	return Uint64Array{unsafeArray(, , )}
}

func ( Uint64Array) () int                   { return int(.len) }
func ( Uint64Array) ( int) uint64         { return *(*uint64)(.index()) }
func ( Uint64Array) (,  int) Uint64Array { return Uint64Array{.slice(, )} }
func ( Uint64Array) () Uint8Array     { return Uint8Array{.array} }
func ( Uint64Array) () Uint16Array   { return Uint16Array{.array} }
func ( Uint64Array) () Uint32Array   { return Uint32Array{.array} }
func ( Uint64Array) () Array         { return Array{.array} }

type Uint128Array struct{ array }

func ( [][16]byte) Uint128Array {
	return Uint128Array{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) Uint128Array {
	return Uint128Array{unsafeArray(, , )}
}

func ( Uint128Array) () int                    { return int(.len) }
func ( Uint128Array) ( int) [16]byte        { return *(*[16]byte)(.index()) }
func ( Uint128Array) (,  int) Uint128Array { return Uint128Array{.slice(, )} }
func ( Uint128Array) () Uint8Array      { return Uint8Array{.array} }
func ( Uint128Array) () Uint16Array    { return Uint16Array{.array} }
func ( Uint128Array) () Uint32Array    { return Uint32Array{.array} }
func ( Uint128Array) () Uint64Array    { return Uint64Array{.array} }
func ( Uint128Array) () Array          { return Array{.array} }

type StringArray struct{ array }

func ( []string) StringArray {
	const  = unsafe.Sizeof("")
	return StringArray{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) StringArray {
	return StringArray{unsafeArray(, , )}
}

func ( StringArray) () int                   { return int(.len) }
func ( StringArray) ( int) string         { return *(*string)(.index()) }
func ( StringArray) (,  int) StringArray { return StringArray{.slice(, )} }
func ( StringArray) () Array         { return Array{.array} }

type TimeArray struct{ array }

func ( []time.Time) TimeArray {
	return TimeArray{makeArray()}
}

func ( unsafe.Pointer,  int,  uintptr) TimeArray {
	return TimeArray{unsafeArray(, , )}
}

func ( TimeArray) () int                 { return int(.len) }
func ( TimeArray) ( int) time.Time    { return *(*time.Time)(.index()) }
func ( TimeArray) (,  int) TimeArray { return TimeArray{.slice(, )} }
func ( TimeArray) () Array       { return Array{.array} }