Skip to content

Commit 9457406

Browse files
authored
Merge pull request #38463 from wongzigii/SR-14886
Check withContiguousStorageIfAvailable before copying byte by byte
2 parents b8d2f26 + 26b3c55 commit 9457406

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

stdlib/public/core/UnsafeRawBufferPointer.swift.gyb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,16 @@ extension Unsafe${Mutable}RawBufferPointer {
418418
guard let position = _position else {
419419
return
420420
}
421+
422+
if source.withContiguousStorageIfAvailable({
423+
(buffer: UnsafeBufferPointer<C.Element>) -> Void in
424+
if let base = buffer.baseAddress {
425+
position.copyMemory(from: base, byteCount: buffer.count)
426+
}
427+
}) != nil {
428+
return
429+
}
430+
421431
for (index, byteValue) in source.enumerated() {
422432
position.storeBytes(
423433
of: byteValue, toByteOffset: index, as: UInt8.self)

test/stdlib/UnsafeRawBufferPointer.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,19 @@ UnsafeRawBufferPointerTestSuite.test("copyMemory.overflow") {
421421
from: UnsafeRawBufferPointer(buffer))
422422
}
423423

424+
// Use copyBytes without contiguous storage
425+
UnsafeRawBufferPointerTestSuite.test("copyBytes.withoutContiguouseStorage") {
426+
let ranges: [Range<UInt8>] = [0..<2, 1..<3, 2..<4, 3..<5]
427+
var array = [UInt8](repeating: 0, count: 2)
428+
for range in ranges {
429+
array.withUnsafeMutableBytes { byte in
430+
byte.copyBytes(from: range)
431+
}
432+
expectEqual(array.count, range.count)
433+
expectEqual(array, Array(range))
434+
}
435+
}
436+
424437
UnsafeRawBufferPointerTestSuite.test("copyBytes.sequence.overflow") {
425438
var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: 3, alignment: MemoryLayout<UInt>.alignment)
426439
defer { buffer.deallocate() }

0 commit comments

Comments
 (0)