Skip to content

Commit 92335b1

Browse files
authored
Merge pull request swiftlang#38677 from glessard/sr14491-v1
[stdlib] fast path for UMBP.initialize<C>(from: C) when C is a Slice
2 parents aff95bf + 3302750 commit 92335b1

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

stdlib/public/core/Sequence.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,13 @@ extension Sequence {
11401140
@inlinable
11411141
public __consuming func _copyContents(
11421142
initializing buffer: UnsafeMutableBufferPointer<Element>
1143+
) -> (Iterator,UnsafeMutableBufferPointer<Element>.Index) {
1144+
return _copySequenceContents(initializing: buffer)
1145+
}
1146+
1147+
@_alwaysEmitIntoClient
1148+
internal __consuming func _copySequenceContents(
1149+
initializing buffer: UnsafeMutableBufferPointer<Element>
11431150
) -> (Iterator,UnsafeMutableBufferPointer<Element>.Index) {
11441151
var it = self.makeIterator()
11451152
guard var ptr = buffer.baseAddress else { return (it,buffer.startIndex) }

stdlib/public/core/Slice.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,22 @@ extension Slice: Collection {
229229
}
230230
}
231231

232+
extension Slice {
233+
@_alwaysEmitIntoClient
234+
public __consuming func _copyContents(
235+
initializing buffer: UnsafeMutableBufferPointer<Element>
236+
) -> (Iterator, UnsafeMutableBufferPointer<Element>.Index) {
237+
if let (_, copied) = self.withContiguousStorageIfAvailable({
238+
$0._copyContents(initializing: buffer)
239+
}) {
240+
let position = index(startIndex, offsetBy: copied)
241+
return (Iterator(_elements: self, _position: position), copied)
242+
}
243+
244+
return _copySequenceContents(initializing: buffer)
245+
}
246+
}
247+
232248
extension Slice: BidirectionalCollection where Base: BidirectionalCollection {
233249
@inlinable // generic-performance
234250
public func index(before i: Index) -> Index {

validation-test/stdlib/UnsafeBufferPointer.swift.gyb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,22 @@ UnsafeMutableBufferPointerTestSuite.test("withContiguous(Mutable)StorageIfAvaila
361361
expectEqual(result1, result2)
362362
}
363363

364+
UnsafeMutableBufferPointerTestSuite.test("initialize(from: Slice)") {
365+
let o = 91
366+
let c = 1_000
367+
let a = Slice(base: Array(0..<c), bounds: o..<c)
368+
369+
let buffer = UnsafeMutableBufferPointer<Int>.allocate(capacity: c-o)
370+
defer { buffer.deallocate() }
371+
372+
var (iterator, copied) = buffer.initialize(from: a)
373+
expectEqual(iterator.next(), nil)
374+
expectEqual(copied, c-o)
375+
376+
let t = buffer.indices.randomElement()!
377+
expectEqual(a[t+o], buffer[t])
378+
}
379+
364380
UnsafeMutableBufferPointerTestSuite.test("Slice.withContiguousStorageIfAvailable") {
365381
guard #available(macOS 10.16, iOS 14.0, watchOS 7.0, tvOS 14.0, *) else {
366382
return

0 commit comments

Comments
 (0)