mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[String] Custom iterator for UnicodeScalarView
Provide a custom iterator rather than relying a the IndexingIterator, as an indexing model is less efficient for stateful processing of strings. Provides around a 30% speedup.
This commit is contained in:
@@ -161,15 +161,44 @@ extension String.UnicodeScalarView: BidirectionalCollection {
|
||||
@inline(__always) get {
|
||||
String(_guts)._boundsCheck(position)
|
||||
let i = _guts.scalarAlign(position)
|
||||
if _fastPath(_guts.isFastUTF8) {
|
||||
return _guts.fastUTF8Scalar(startingAt: i.encodedOffset)
|
||||
}
|
||||
|
||||
return _foreignSubscript(aligned: i)
|
||||
return _guts.errorCorrectedScalar(startingAt: i.encodedOffset).0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension String.UnicodeScalarView {
|
||||
@_fixed_layout
|
||||
public struct Iterator: IteratorProtocol {
|
||||
@usableFromInline
|
||||
internal var _guts: _StringGuts
|
||||
|
||||
@usableFromInline
|
||||
internal var _position: Int = 0
|
||||
|
||||
@usableFromInline
|
||||
internal var _end: Int
|
||||
|
||||
@inlinable
|
||||
internal init(_ guts: _StringGuts) {
|
||||
self._guts = guts
|
||||
self._end = guts.count
|
||||
}
|
||||
|
||||
@inlinable
|
||||
public mutating func next() -> Unicode.Scalar? {
|
||||
guard _fastPath(_position < _end) else { return nil }
|
||||
|
||||
let (result, len) = _guts.errorCorrectedScalar(startingAt: _position)
|
||||
_position &+= len
|
||||
return result
|
||||
}
|
||||
}
|
||||
@inlinable
|
||||
public __consuming func makeIterator() -> Iterator {
|
||||
return Iterator(_guts)
|
||||
}
|
||||
}
|
||||
|
||||
extension String.UnicodeScalarView: CustomStringConvertible {
|
||||
@inlinable
|
||||
public var description: String {
|
||||
@@ -403,14 +432,4 @@ extension String.UnicodeScalarView {
|
||||
|
||||
return i.encoded(offsetBy: -len)
|
||||
}
|
||||
|
||||
@usableFromInline @inline(never)
|
||||
@_effects(releasenone)
|
||||
internal func _foreignSubscript(aligned i: Index) -> Unicode.Scalar {
|
||||
_sanityCheck(_guts.isForeign)
|
||||
_sanityCheck(_guts.isOnUnicodeScalarBoundary(i),
|
||||
"should of been aligned prior")
|
||||
|
||||
return _guts.foreignErrorCorrectedScalar(startingAt: i).0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user