@@ -361,6 +361,8 @@ extension Unicode.DefaultScalarView.Iterator : IteratorProtocol, Sequence {
361
361
extension Unicode . DefaultScalarView {
362
362
struct Index {
363
363
var codeUnitIndex : CodeUnits . Index
364
+ var scalar : UnicodeScalar
365
+ var stride : UInt8
364
366
}
365
367
}
366
368
@@ -384,44 +386,52 @@ extension Unicode.DefaultScalarView.Index : Comparable {
384
386
385
387
extension Unicode . DefaultScalarView : Collection {
386
388
public var startIndex : Index {
387
- return Index ( codeUnitIndex: codeUnits. startIndex)
389
+ @inline ( __always)
390
+ get {
391
+ return index (
392
+ after: Index (
393
+ codeUnitIndex: codeUnits. startIndex,
394
+ scalar: UnicodeScalar ( _unchecked: 0 ) ,
395
+ stride: 0 )
396
+ )
397
+ }
388
398
}
389
399
390
400
public var endIndex : Index {
391
- return Index ( codeUnitIndex: codeUnits. endIndex)
392
- }
393
-
394
- public subscript( i: Index ) -> UnicodeScalar {
395
401
@inline ( __always)
396
402
get {
397
- var d = Encoding . ForwardDecoder ( )
398
- var input = codeUnits [ i. codeUnitIndex..< codeUnits. endIndex] . makeIterator ( )
399
- switch d. parseOne ( & input) {
400
- case . valid( let scalarContent) :
401
- return Encoding . ForwardDecoder. decodeOne ( scalarContent)
402
- case . invalid:
403
- return UnicodeScalar ( _unchecked: 0xFFFD )
404
- case . emptyInput:
405
- fatalError ( " subscripting at endIndex " )
406
- }
403
+ return Index (
404
+ codeUnitIndex: codeUnits. endIndex,
405
+ scalar: UnicodeScalar ( _unchecked: 0 ) ,
406
+ stride: 0 )
407
407
}
408
408
}
409
409
410
+ public subscript( i: Index ) -> UnicodeScalar {
411
+ @inline ( __always) get { return i. scalar }
412
+ }
413
+
410
414
@inline ( __always)
411
415
public func index( after i: Index ) -> Index {
416
+ let nextPosition = codeUnits. index (
417
+ i. codeUnitIndex, offsetBy: numericCast ( i. stride) )
418
+ var i = IndexingIterator (
419
+ _elements: codeUnits, _position: nextPosition
420
+ )
412
421
var d = Encoding . ForwardDecoder ( )
413
- var input = codeUnits [ i. codeUnitIndex..< codeUnits. endIndex] . makeIterator ( )
414
- switch d. parseOne ( & input) {
422
+ switch d. parseOne ( & i) {
415
423
case . valid( let scalarContent) :
416
424
return Index (
417
- codeUnitIndex: codeUnits. index (
418
- i. codeUnitIndex, offsetBy: numericCast ( scalarContent. count) ) )
419
- case . invalid( let l) :
425
+ codeUnitIndex: nextPosition,
426
+ scalar: Encoding . ForwardDecoder. decodeOne ( scalarContent) ,
427
+ stride: numericCast ( scalarContent. count) )
428
+ case . invalid( let stride) :
420
429
return Index (
421
- codeUnitIndex: codeUnits. index (
422
- i. codeUnitIndex, offsetBy: numericCast ( l) ) )
430
+ codeUnitIndex: nextPosition,
431
+ scalar: UnicodeScalar ( _unchecked: 0xfffd ) ,
432
+ stride: numericCast ( stride) )
423
433
case . emptyInput:
424
- fatalError ( " indexing past endIndex" )
434
+ return endIndex
425
435
}
426
436
}
427
437
}
@@ -461,19 +471,24 @@ extension Unicode.DefaultScalarView : BidirectionalCollection {
461
471
@inline ( __always)
462
472
public func index( before i: Index ) -> Index {
463
473
var d = Encoding . ReverseDecoder ( )
464
- var input = ReverseIndexingIterator (
474
+
475
+ var more = ReverseIndexingIterator (
465
476
_elements: codeUnits, _position: i. codeUnitIndex)
466
- switch d. parseOne ( & input) {
477
+
478
+ switch d. parseOne ( & more) {
467
479
case . valid( let scalarContent) :
480
+ let d : CodeUnits . IndexDistance = - numericCast( scalarContent. count)
468
481
return Index (
469
- codeUnitIndex: codeUnits. index (
470
- i. codeUnitIndex, offsetBy: - numericCast( scalarContent. count) ) )
471
- case . invalid( let l) :
482
+ codeUnitIndex: codeUnits. index ( i. codeUnitIndex, offsetBy: d) ,
483
+ scalar: Encoding . ReverseDecoder. decodeOne ( scalarContent) ,
484
+ stride: numericCast ( scalarContent. count) )
485
+ case . invalid( let stride) :
486
+ let d : CodeUnits . IndexDistance = - numericCast( stride)
472
487
return Index (
473
- codeUnitIndex: codeUnits. index (
474
- i . codeUnitIndex , offsetBy : - numericCast ( l ) ) )
475
- case . emptyInput :
476
- fatalError ( " indexing past startIndex " )
488
+ codeUnitIndex: codeUnits. index ( i . codeUnitIndex , offsetBy : d ) ,
489
+ scalar : UnicodeScalar ( _unchecked : 0xfffd ) ,
490
+ stride : numericCast ( stride ) )
491
+ case . emptyInput : fatalError ( " index out of bounds. " )
477
492
}
478
493
}
479
494
}
0 commit comments