74 lines
2.1 KiB
Go
74 lines
2.1 KiB
Go
package mem
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
// SizeOf returns the size (in bytes) of the given type.
|
|
//
|
|
// Not to be confused with [unsafe.Sizeof] which returns the size of a type via an expression.
|
|
func SizeOf[T any]() uintptr {
|
|
var zero T
|
|
return unsafe.Sizeof(zero)
|
|
}
|
|
|
|
// AlignOf returns the alignment (in bytes) of the given type.
|
|
//
|
|
// Not to be confused with [unsafe.AlignOf] which returns the alignment of a type via an expression.
|
|
func AlignOf[T any]() uintptr {
|
|
var zero T
|
|
return unsafe.Alignof(zero)
|
|
}
|
|
|
|
// BitCast performs a bit conversion between two types of the same size.
|
|
//
|
|
// BitCast panics if the sizes of the types differ.
|
|
func BitCast[TOut any, TIn any](value *TIn) TOut {
|
|
if SizeOf[TOut]() != SizeOf[TIn]() {
|
|
panic("bitcast: sizes of types must match")
|
|
}
|
|
return *((*TOut)(unsafe.Pointer(value)))
|
|
}
|
|
|
|
// Copy copies size number of bytes from src into dst.
|
|
//
|
|
// Returns dst.
|
|
func Copy(dst, src unsafe.Pointer, size uintptr) unsafe.Pointer {
|
|
copy(unsafe.Slice((*byte)(dst), size), unsafe.Slice((*byte)(src), size))
|
|
return dst
|
|
}
|
|
|
|
// Clear overwrites 'count' number of bytes in 'dst' with a particular value.
|
|
//
|
|
// Returns dst.
|
|
func Clear(dst unsafe.Pointer, value byte, count uintptr) unsafe.Pointer {
|
|
b := (*byte)(dst)
|
|
for range count {
|
|
*b = value
|
|
b = (*byte)(unsafe.Add(dst, 1))
|
|
}
|
|
return dst
|
|
}
|
|
|
|
// Zero overwrites 'count' number of bytes in 'dst' with zeros.
|
|
//
|
|
// Returns dst.
|
|
func Zero(dst unsafe.Pointer, count uintptr) unsafe.Pointer {
|
|
return Clear(dst, 0, count)
|
|
}
|
|
|
|
// AlignForward returns an address align to the next power-of-two alignment.
|
|
func AlignForward(address uintptr, alignment uintptr) uintptr {
|
|
if alignment == 0 || (alignment&(alignment-1)) != 0 {
|
|
panic("alignforward: alignment must be a power of two")
|
|
}
|
|
return (address + alignment - 1) &^ (alignment - 1)
|
|
}
|
|
|
|
// AlignBackward returns an address align to the previous power-of-two alignment.
|
|
func AlignBackward(address uintptr, alignment uintptr) uintptr {
|
|
if alignment == 0 || (alignment&(alignment-1)) != 0 {
|
|
panic("alignbackward: alignment must be a power of two")
|
|
}
|
|
return address &^ (alignment - 1)
|
|
}
|