i will admit 99% of the time i use Array.init(unsafeUninitializedCapacity:initializingWith:), i completely ignore memory management and i just assign through UnsafeMutableBufferPointer.subscript(_:) because the element type is trivial.
let _:[UInt8] = .init(unsafeUninitializedCapacity: elements.count)
{
for (i, value):(Int, UInt8) in elements
{
$0[i] = value
}
$1 = elements.count
}
but if the element type is not trivial, then you actually have to initialize instead of assign, and UnsafeMutableBufferPointer doesn’t have an API to initialize a single element of the buffer at a particular index, instead you have to optionally unwrap the baseAddress and perform pointer arithmetic:
let _:[C] = .init(unsafeUninitializedCapacity: elements.count)
{
guard let start:UnsafeMutablePointer<C> = $0.baseAddress
else
{
$1 = 0
return
}
for (i, value):(Int, C) in elements
{
(start + i).initialize(to: value)
}
$1 = elements.count
}
Alejandro
(Alejandro Alonso)
2
UnsafeMutableBufferPointer<T>.initializeElement(at: Int, to: T)?
3 Likes
aha, that’s exactly what i needed! is it new in 5.8?
Alejandro
(Alejandro Alonso)
4
It looks like it was added 10 months ago, but it is marked @_alwaysEmitIntoClient so as long as you have a new enough stdlib to compile against you should have it and be able to use it as far back as you want.
5 Likes