@@ -487,6 +487,12 @@ extension String.UTF8View {
487
487
internal var _sourceIndex : Int
488
488
@_versioned // FIXME(sil-serialize-all)
489
489
internal var _buffer : _OutputBuffer
490
+
491
+ @_versioned
492
+ internal var _endIndex : Int
493
+
494
+ @_versioned
495
+ internal var _asciiPointer : UnsafePointer < UInt8 > ?
490
496
}
491
497
492
498
public func makeIterator( ) -> Iterator {
@@ -499,8 +505,14 @@ extension String.UTF8View.Iterator : IteratorProtocol {
499
505
@_versioned // FIXME(sil-serialize-all)
500
506
internal init ( _ guts: _StringGuts ) {
501
507
self . _guts = guts
502
- _sourceIndex = 0
503
- _buffer = 0
508
+ self . _sourceIndex = 0
509
+ self . _buffer = 0
510
+ self . _endIndex = self . _guts. count
511
+ if _fastPath ( self . _guts. _isContiguous && self . _guts. isASCII) {
512
+ self . _asciiPointer = self . _guts. _unmanagedASCIIView. start
513
+ } else {
514
+ self . _asciiPointer = nil
515
+ }
504
516
}
505
517
506
518
@_inlineable // FIXME(sil-serialize-all)
@@ -510,24 +522,23 @@ extension String.UTF8View.Iterator : IteratorProtocol {
510
522
_buffer >>= 8
511
523
return r
512
524
}
513
- if _slowPath ( _sourceIndex == _guts. count) { return nil }
514
-
515
- let isContiguous = _guts. _isContiguous
525
+ if _slowPath ( _sourceIndex == _endIndex) { return nil }
516
526
517
527
defer { _fixLifetime ( _guts) }
518
-
519
- if _fastPath ( isContiguous) {
520
- if _guts. isASCII {
521
- let ascii = _guts. _unmanagedASCIIView. start
522
- let result = ascii [ _sourceIndex]
528
+
529
+ if _fastPath ( self . _asciiPointer != nil ) {
530
+ let ascii = self . _asciiPointer. _unsafelyUnwrappedUnchecked
531
+ let result = ascii [ _sourceIndex]
532
+ _sourceIndex += 1
533
+ for i in 0 ..< _OutputBuffer. bitWidth>>3 {
534
+ if _sourceIndex == _endIndex { break }
535
+ _buffer |= _OutputBuffer ( ascii [ _sourceIndex] &+ 1 ) &<< ( i << 3 )
523
536
_sourceIndex += 1
524
- for i in 0 ..< _OutputBuffer. bitWidth>>3 {
525
- if _sourceIndex == _guts. count { break }
526
- _buffer |= _OutputBuffer ( ascii [ _sourceIndex] &+ 1 ) &<< ( i << 3 )
527
- _sourceIndex += 1
528
- }
529
- return result
530
537
}
538
+ return result
539
+ }
540
+
541
+ if _fastPath ( _guts. _isContiguous) {
531
542
return _next ( refillingFrom: _guts. _unmanagedUTF16View. buffer)
532
543
}
533
544
@@ -546,7 +557,7 @@ extension String.UTF8View.Iterator : IteratorProtocol {
546
557
var shift = 0
547
558
548
559
// ASCII fastpath
549
- while _sourceIndex != _guts . endIndex && shift < _OutputBuffer. bitWidth {
560
+ while _sourceIndex != _endIndex && shift < _OutputBuffer. bitWidth {
550
561
let u = _guts [ _sourceIndex]
551
562
if u >= 0x80 { break }
552
563
_buffer |= _OutputBuffer ( UInt8 ( truncatingIfNeeded: u &+ 1 ) ) &<< shift
0 commit comments