Skip to content

Commit 2bc053f

Browse files
committed
[stdlib] implement _copyContents for Slice
`Sequence._copyContents(initializing:)` is the function relied on by `UnsafeMutableBufferPointer` for performant initialization from Collections. Until now, `Slice<Base: Collection>` has not had its own implementation, and therefore fell back to the default version implemented on `Sequence`. This implementation adds an attempted fast path, using `withContiguousStorageIfAvailable`. If that fails, the `Sequence` algorithm is used, as before. This resolves https://bugs.swift.org/browse/SR-14491
1 parent a9e0af4 commit 2bc053f

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

stdlib/public/core/Slice.swift

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

232+
extension Slice {
233+
@inlinable
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 distance = buffer.distance(from: buffer.startIndex, to: copied)
241+
let i = index(startIndex, offsetBy: distance)
242+
return (Iterator(_elements: self, _position: i), copied)
243+
}
244+
245+
return _copySequenceContents(initializing: buffer)
246+
}
247+
}
248+
232249
extension Slice: BidirectionalCollection where Base: BidirectionalCollection {
233250
@inlinable // generic-performance
234251
public func index(before i: Index) -> Index {

0 commit comments

Comments
 (0)