It seems that the UnsafeMutableBufferPointer subscript supports both get and set operations, but it uses the Slice<UnsafeMutableBufferPointer> type. So, you can make this work as follows:
Is the UInt8 in the above example just an example? Or are you working with blocks of untyped memory? If it’s the latter, I recommend a raw buffer pointer (UnsafeMutableRawBufferPointer) which has a copyBytes(from:) method.
You can write a subscript that enables the nice syntax for assigning values from any Sequence into a slice of any MutableCollection:
Generic slice assignment subscript
extension MutableCollection {
subscript<S: Sequence>(_ range: Range<Index>) -> S
where S.Element == Element
{
set {
var i = range.lowerBound
for x in newValue {
if i >= range.upperBound { break }
self[i] = x
formIndex(after: &i)
}
}
@available(*, unavailable)
get { fatalError() }
}
subscript<R: RangeExpression, S: Sequence>(_ range: R) -> S
where R.Bound == Index, S.Element == Element
{
set { self[range.relative(to: self)] = newValue }
@available(*, unavailable)
get { fatalError() }
}
}
That really “should be” a set-only subscript, which we approximate here by marking the getter as unavailable.
This example implementation does not enforce that the sequence and index range have the same number of elements, but you could do so if desired. It does guarantee that nothing outside the slice will be modified, and the length of the collection will not change.
It seems like that it could be nice if just UnsafeMutableBufferPointer had implemented conformance to RangeReplaceableCollection, that way this operation would be just a buffer.replaceSubrange(3...5, with: [1, 2, 3]). It would've make sense to me have such conformance, but maybe I'm missing something and there is a good rational for it to not conform...
Unsafe[Raw]MutableBufferPointer cannot conform to RangeReplaceableCollection because it cannot resize itself. Remember that these memory allocations are unmanaged.