Skip to content

Commit 9fbf359

Browse files
authored
Merge pull request swiftlang#38828 from glessard/sr9604
[stdlib] implement _copyContents for UnsafeRawBufferPointer
2 parents 47f156f + b970d75 commit 9fbf359

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

stdlib/public/core/UnsafeRawBufferPointer.swift.gyb

+20
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,26 @@ extension Unsafe${Mutable}RawBufferPointer: Sequence {
145145
public func makeIterator() -> Iterator {
146146
return Iterator(_position: _position, _end: _end)
147147
}
148+
149+
/// Copies the elements of `self` to the memory at `destination.baseAddress`,
150+
/// stopping when either `self` or `destination` is exhausted.
151+
///
152+
/// - Returns: an iterator over any remaining elements of `self` and the
153+
/// number of elements copied.
154+
@inlinable // unsafe-performance
155+
@_alwaysEmitIntoClient
156+
public func _copyContents(
157+
initializing destination: UnsafeMutableBufferPointer<UInt8>
158+
) -> (Iterator, UnsafeMutableBufferPointer<UInt8>.Index) {
159+
guard let s = _position, let e = _end, e > s, !destination.isEmpty else {
160+
return (makeIterator(), 0)
161+
}
162+
let destinationAddress = destination.baseAddress._unsafelyUnwrappedUnchecked
163+
let d = UnsafeMutableRawPointer(destinationAddress)
164+
let n = Swift.min(destination.count, self.count)
165+
d.copyMemory(from: s, byteCount: n)
166+
return (Iterator(_position: s.advanced(by: n), _end: e), n)
167+
}
148168
}
149169

150170
extension Unsafe${Mutable}RawBufferPointer: ${Mutable}Collection {

test/stdlib/UnsafeRawBufferPointer.swift

+12
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,18 @@ UnsafeRawBufferPointerTestSuite.test("subscript.range.wide") {
407407
buffer[0..<2] = buffer[0..<3]
408408
}
409409

410+
UnsafeRawBufferPointerTestSuite.test("_copyContents") {
411+
let a = Array<UInt8>(0..<20)
412+
let b = UnsafeMutableBufferPointer<UInt8>.allocate(capacity: 10*a.count)
413+
defer { b.deallocate() }
414+
var (unwritten, written) = a.withUnsafeBytes {
415+
bytes in
416+
bytes._copyContents(initializing: b)
417+
}
418+
expectNil(unwritten.next())
419+
expectEqual(written, a.count)
420+
}
421+
410422
UnsafeRawBufferPointerTestSuite.test("copyMemory.overflow") {
411423
var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: 3, alignment: MemoryLayout<UInt>.alignment)
412424
defer { buffer.deallocate() }

0 commit comments

Comments
 (0)