Take Delight in Small Joys
Extensions everywhere
This is a small post about a small joy. I really enjoy how natural extensions can feel in Swift.
I consider it quite unfortunate that UnsafeMutableRawBufferPointer.baseAddress
is optional. It makes that type so ugly to use in practice. I also dislike having to specify alignment on allocation; a sensible default is Int.bitWidth / 8
on most platforms.
With extensions we can solve these problems quite easily. The solution feels just as natural to use as what ships in the standard library
First, we'll want a tiny sanity check in debug builds to make sure our alignment calculations don't produce nonsense. This is a minor bit trick for positive integers: A power-of-two number in binary has exactly one bit set. Subtracting one flips all the bits below that to 1s, so 8 (0b1000
) - 1 gives 7 (0b0111
). Those two numbers have no bits in common so a bitwise-AND should yield zero. This fails on zero so we check for that separately.
extension BinaryInteger {
var isPositivePowerOf2: Bool {
@inline(__always)
get {
return (self & (self - 1)) == 0 && self != 0
}
}
}
Now let's make allocate use natural integer width alignment by default. This alignment may be more than we need but it is almost always sufficient for anything we care to store in the buffer. The assertion is only active in debug builds. That should be more than sufficient; we know it will be true on every platform Swift currently supports.
extension UnsafeMutableRawBufferPointer {
static func allocate(byteCount: Int) -> UnsafeMutableRawBufferPointer {
let alignment = Int.bitWidth / 8
assert(alignment.isPositivePowerOf2, "expected power of two")
return self.allocate(byteCount: byteCount, alignment: alignment)
}
}
Last but not least let's add a base
property that hides the force-unwrapping.
extension UnsafeMutableRawBufferPointer {
var base: UnsafeMutableRawPointer {
return baseAddress!
}
}
extension UnsafeRawBufferPointer {
var base: UnsafeRawPointer {
return baseAddress!
}
}
Easy-peasy.
This blog represents my own personal opinion and is not endorsed by my employer.