Is there a simpler way of initializing it with the correct alignment?
proc getAlignPadding(p: pointer, align: int): BiggestUInt =
cast[BiggestUInt](p) mod BiggestUInt(align)
# same interface as std::align
proc align(align: int, size: int, p: var pointer, space: var BiggestUInt):
bool =
let padding = getAlignPadding(p, align)
if padding + BiggestUInt(size) > space:
p = nil
false
else:
p = cast[pointer](cast[BiggestUInt](p) + padding)
space -= padding
true
proc align[T](p: var pointer, space: var BiggestUInt): bool =
align(alignof(T), sizeof(T), p, space)
proc inPlaceAligned[T](p: pointer, value: sink T) {.nodestroy.} =
var dest = cast[ptr T](p)
dest[] = value
template inPlace[T](p: pointer, space: SomeInteger, value: sink T): pointer
=
block:
var p = p
var space = BiggestUInt(space)
if align[T](p, space):
inPlaceAligned(p, value)
p
template inPlace[T](buffer: openArray[byte], value: sink T): pointer =
block:
var p: pointer = buffer[0].addr()
var space = BiggestUInt(buffer.len())
if align[T](p, space):
inPlaceAligned(p, value)
p
proc bufferAs[T](buffer: openArray[byte]): ptr T =
var p: pointer = buffer[0].addr()
var space = BiggestUInt(buffer.len())
if align[T](p, space):
cast[ptr T](p)
else:
nil
proc getDestroyAt[T](): proc(p: pointer) =
proc(p: pointer) = cast[ptr T](p)[].`=destroy`()
Run
type Person = object
age: int
name: string
type Dog = object
age {.align(128).}: int
name: string
proc `=destroy`(x: Person) =
debugEcho "Person destroyed"
proc `=destroy`(x: Dog) =
debugEcho "Dog destroyed"
block:
var buffer: array[sizeof(Person), byte]
echo "initializing Person"
var p = inPlace[Person](buffer, Person(age: 30, name: "Shaggy"))
var destroyAt = getDestroyAt[Person]()
if p.isNil():
echo "buffer too small"
else:
echo bufferAs[Person](buffer)[]
destroyAt(p)
echo ""
block:
var buffer: array[sizeof(Dog), byte]
echo "initializing Dog"
var p = inPlace[Dog](buffer, Dog(age: 30, name: "Scooby"))
var destroyAt = getDestroyAt[Dog]()
if p.isNil():
echo "buffer too small"
else:
echo bufferAs[Dog](buffer)[]
destroyAt(p)
echo ""
Run
initializing Person
(age: 30, name: "Shaggy")
Person destroyed
initializing Dog
buffer too small
Run