From af036db7bdf082f5f19e0b2b62bdd2985ba72ad7 Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Mon, 9 Aug 2021 17:48:03 -0600 Subject: [PATCH 1/2] [stdlib] implement _copyContents for UnsafeRawPointer --- .../core/UnsafeRawBufferPointer.swift.gyb | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb b/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb index 51f99f4f0f820..c01039cb7b9a6 100644 --- a/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb +++ b/stdlib/public/core/UnsafeRawBufferPointer.swift.gyb @@ -145,6 +145,26 @@ extension Unsafe${Mutable}RawBufferPointer: Sequence { public func makeIterator() -> Iterator { return Iterator(_position: _position, _end: _end) } + + /// Copies the elements of `self` to the memory at `destination.baseAddress`, + /// stopping when either `self` or `destination` is exhausted. + /// + /// - Returns: an iterator over any remaining elements of `self` and the + /// number of elements copied. + @inlinable // unsafe-performance + @_alwaysEmitIntoClient + public func _copyContents( + initializing destination: UnsafeMutableBufferPointer + ) -> (Iterator, UnsafeMutableBufferPointer.Index) { + guard let s = _position, let e = _end, e > s, !destination.isEmpty else { + return (makeIterator(), 0) + } + let destinationAddress = destination.baseAddress._unsafelyUnwrappedUnchecked + let d = UnsafeMutableRawPointer(destinationAddress) + let n = Swift.min(destination.count, self.count) + d.copyMemory(from: s, byteCount: n) + return (Iterator(_position: s.advanced(by: n), _end: e), n) + } } extension Unsafe${Mutable}RawBufferPointer: ${Mutable}Collection { From b970d7500abd06965c328649049748d93bd22e5e Mon Sep 17 00:00:00 2001 From: Guillaume Lessard Date: Thu, 19 Aug 2021 03:30:06 -0600 Subject: [PATCH 2/2] [test] exercise UnsafeRawBufferPointer._copyContents --- test/stdlib/UnsafeRawBufferPointer.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/stdlib/UnsafeRawBufferPointer.swift b/test/stdlib/UnsafeRawBufferPointer.swift index 166d4b2717c51..d77e74135a318 100644 --- a/test/stdlib/UnsafeRawBufferPointer.swift +++ b/test/stdlib/UnsafeRawBufferPointer.swift @@ -407,6 +407,18 @@ UnsafeRawBufferPointerTestSuite.test("subscript.range.wide") { buffer[0..<2] = buffer[0..<3] } +UnsafeRawBufferPointerTestSuite.test("_copyContents") { + let a = Array(0..<20) + let b = UnsafeMutableBufferPointer.allocate(capacity: 10*a.count) + defer { b.deallocate() } + var (unwritten, written) = a.withUnsafeBytes { + bytes in + bytes._copyContents(initializing: b) + } + expectNil(unwritten.next()) + expectEqual(written, a.count) +} + UnsafeRawBufferPointerTestSuite.test("copyMemory.overflow") { var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: 3, alignment: MemoryLayout.alignment) defer { buffer.deallocate() }