Thanks to everyone who participated so far. It looks like @Jens and @Nevin are co-winners. (Somehow, @Jens was also competing with himself, and managed to beat himself soundly. Not sure how that could happen. Maybe it's a quantum entanglement effect.) These are the winning implementations:
func fill<T>(_ buffer: UnsafeMutableRawPointer, with array: [T]) {
buffer.copyMemory(from: array, byteCount: array.count * MemoryLayout<T>.stride)
}
func fill<T>(_ buffer: UnsafeMutableRawPointer, with array: [T]) {
buffer.initializeMemory(as: T.self, from: array, count: array.count)
}
It seems to me that these solutions are pretty compact, but don't really make Swift look good (not Jens or Nevin's fault in any way). The problem for me is that pesky and redundant-looking count. If array can be coerced to produce an unsafe pointer of some kind without any additional source code decoration, then surely it can produce an unsafe buffer pointer that has the count built in. It seems like the correct answers ought to be:
func fill<T>(_ buffer: UnsafeMutableRawPointer, with array: [T]) {
buffer.copyMemory(from: array)
}
func fill<T>(_ buffer: UnsafeMutableRawPointer, with array: [T]) {
buffer.initializeMemory(as: T.self, from: array)
}
Apart from anything else, in this simple use-case, there'd be no reason to define this fill function at all, since the single line of implementation could just as well be written at the call site, with excellent readability.
Looking at this at a slightly higher conceptual level, I'm beginning to think that it's actively harmful to have Unsafe…Pointer and Unsafe…BufferPointer both floating around as peers in Swift's conceptual space. We only really need Unsafe…BufferPointer because — still at the conceptual level — an Unsafe…Pointer could adequately be represented as a buffer pointer with a count of 1 element.
(Yes, I know that Unsafe…Pointer is for direct interop with C, and I understand that we might still want it to exist. I'm just thinking we should try to hide it better. Maybe with a leading underscore.)
If we could get Unsafe…Pointer out of our day-to-day thinking, we'd eliminate the perceived need to force-cast between Unsafe…Pointer and Unsafe…BufferPointer, which is currently awkward to say the least. We'd also be able to leverage the buffer pointer's count attribute to make APIs safer and more readable, as I've shown in the hypothetical examples above. Most importantly, we'd significantly reduce the complexity of the unsafe pointer types' conceptual space.