Skip to content

Commit 574e556

Browse files
authored
Merge pull request #16245 from milseman/its_all_about_the_copy_content
[String] Define _copyContents for UTF8View
2 parents 1c5f9da + 17b0ed4 commit 574e556

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

stdlib/public/core/StringUTF8.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,11 @@ extension String.UTF8View.Iterator : IteratorProtocol {
474474
self._endOffset = utf8._guts.count
475475
}
476476

477+
internal mutating func _clear() {
478+
self._nextOffset = self._endOffset
479+
self._buffer = _OutputBuffer()
480+
}
481+
477482
@inlinable // FIXME(sil-serialize-all)
478483
public mutating func next() -> Unicode.UTF8.CodeUnit? {
479484
if _slowPath(_nextOffset == _endOffset) {
@@ -731,3 +736,42 @@ extension String.UTF8View {
731736
return self[bounds.relative(to: self)]
732737
}
733738
}
739+
740+
extension String.UTF8View {
741+
/// Copies `self` into the supplied buffer.
742+
///
743+
/// - Precondition: The memory in `self` is uninitialized. The buffer must
744+
/// contain sufficient uninitialized memory to accommodate `source.underestimatedCount`.
745+
///
746+
/// - Postcondition: The `Pointee`s at `buffer[startIndex..<returned index]` are
747+
/// initialized.
748+
public func _copyContents(
749+
initializing buffer: UnsafeMutableBufferPointer<Iterator.Element>
750+
) -> (Iterator,UnsafeMutableBufferPointer<Iterator.Element>.Index) {
751+
guard var ptr = buffer.baseAddress else {
752+
_preconditionFailure(
753+
"Attempt to copy string contents into nil buffer pointer")
754+
}
755+
var it = self.makeIterator()
756+
757+
if _guts.isASCII {
758+
defer { _fixLifetime(_guts) }
759+
let asciiView = _guts._unmanagedASCIIView
760+
_precondition(asciiView.count <= buffer.count,
761+
"Insufficient space allocated to copy string contents")
762+
ptr.initialize(from: asciiView.start, count: asciiView.count)
763+
it._clear()
764+
return (it, buffer.index(buffer.startIndex, offsetBy: asciiView.count))
765+
}
766+
else {
767+
for idx in buffer.startIndex..<buffer.count {
768+
guard let x = it.next() else {
769+
return (it, idx)
770+
}
771+
ptr.initialize(to: x)
772+
ptr += 1
773+
}
774+
return (it,buffer.endIndex)
775+
}
776+
}
777+
}

0 commit comments

Comments
 (0)