17
17
// The BASELINE timings come from the existing standard library Codecs
18
18
19
19
/*
20
- for x in BASELINE FORWARD REVERSE SEQUENCE COLLECTION ; do
20
+ for x in BASELINE FORWARD REVERSE SEQUENCE COLLECTION REVERSE_COLLECTION ; do
21
21
echo $x
22
22
swiftc -DBENCHMARK -D$x -O -swift-version 4 UnicodeDecoders.swift -o /tmp/u3-$x
23
23
for i in {1..3}; do
@@ -326,6 +326,11 @@ extension Unicode {
326
326
Encoding: UnicodeEncoding
327
327
> where CodeUnits. Iterator. Element == Encoding . CodeUnit {
328
328
var codeUnits : CodeUnits
329
+ init (
330
+ _ codeUnits: CodeUnits ,
331
+ fromEncoding _: Encoding . Type = Encoding . self) {
332
+ self . codeUnits = codeUnits
333
+ }
329
334
}
330
335
}
331
336
@@ -353,27 +358,23 @@ extension Unicode.DefaultScalarView.Iterator : IteratorProtocol, Sequence {
353
358
}
354
359
}
355
360
356
- extension Unicode {
357
- enum IndexImpl < E: UnicodeEncoding > {
358
- case forward( E . ForwardDecoder , E . ForwardDecoder . EncodedScalar )
359
- case reverse( E . ReverseDecoder , E . ReverseDecoder . EncodedScalar )
360
- }
361
- }
362
361
extension Unicode . DefaultScalarView {
363
362
struct Index {
364
363
var codeUnitIndex : CodeUnits . Index
365
364
}
366
365
}
367
366
368
367
extension Unicode . DefaultScalarView . Index : Comparable {
369
- static func < (
368
+ @inline ( __always)
369
+ public static func < (
370
370
lhs: Unicode . DefaultScalarView < CodeUnits , Encoding > . Index ,
371
371
rhs: Unicode . DefaultScalarView < CodeUnits , Encoding > . Index
372
372
) -> Bool {
373
373
return lhs. codeUnitIndex < rhs. codeUnitIndex
374
374
}
375
375
376
- static func == (
376
+ @inline ( __always)
377
+ public static func == (
377
378
lhs: Unicode . DefaultScalarView < CodeUnits , Encoding > . Index ,
378
379
rhs: Unicode . DefaultScalarView < CodeUnits , Encoding > . Index
379
380
) -> Bool {
@@ -382,41 +383,97 @@ extension Unicode.DefaultScalarView.Index : Comparable {
382
383
}
383
384
384
385
extension Unicode . DefaultScalarView : Collection {
385
- var startIndex : Index {
386
+ public var startIndex : Index {
386
387
return Index ( codeUnitIndex: codeUnits. startIndex)
387
388
}
388
389
389
- var endIndex : Index {
390
+ public var endIndex : Index {
390
391
return Index ( codeUnitIndex: codeUnits. endIndex)
391
392
}
392
393
393
- subscript( i: Index ) -> UnicodeScalar {
394
+ public subscript( i: Index ) -> UnicodeScalar {
395
+ @inline ( __always)
396
+ 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
+ }
407
+ }
408
+ }
409
+
410
+ @inline ( __always)
411
+ public func index( after i: Index ) -> Index {
394
412
var d = Encoding . ForwardDecoder ( )
395
413
var input = codeUnits [ i. codeUnitIndex..< codeUnits. endIndex] . makeIterator ( )
396
414
switch d. parseOne ( & input) {
397
415
case . valid( let scalarContent) :
398
- return Encoding . ForwardDecoder. decodeOne ( scalarContent)
399
- case . invalid:
400
- return UnicodeScalar ( _unchecked: 0xFFFD )
416
+ return Index (
417
+ codeUnitIndex: codeUnits. index (
418
+ i. codeUnitIndex, offsetBy: numericCast ( scalarContent. count) ) )
419
+ case . invalid( let l) :
420
+ return Index (
421
+ codeUnitIndex: codeUnits. index (
422
+ i. codeUnitIndex, offsetBy: numericCast ( l) ) )
401
423
case . emptyInput:
402
- fatalError ( " subscripting at endIndex" )
424
+ fatalError ( " indexing past endIndex" )
403
425
}
404
426
}
427
+ }
405
428
406
- func index( after i: Index ) -> Index {
407
- var d = Encoding . ForwardDecoder ( )
408
- var input = codeUnits [ i. codeUnitIndex..< codeUnits. endIndex] . makeIterator ( )
429
+ // This should go in the standard library; see
430
+ // https://github.com/apple/swift/pull/9074 and
431
+ // https://bugs.swift.org/browse/SR-4721
432
+ @_fixed_layout
433
+ public struct ReverseIndexingIterator <
434
+ Elements : BidirectionalCollection
435
+ > : IteratorProtocol , Sequence {
436
+
437
+ @_inlineable
438
+ @inline ( __always)
439
+ /// Creates an iterator over the given collection.
440
+ public /// @testable
441
+ init ( _elements: Elements , _position: Elements . Index ) {
442
+ self . _elements = _elements
443
+ self . _position = _position
444
+ }
445
+
446
+ @_inlineable
447
+ @inline ( __always)
448
+ public mutating func next( ) -> Elements . _Element ? {
449
+ guard _fastPath ( _position != _elements. startIndex) else { return nil }
450
+ _position = _elements. index ( before: _position)
451
+ return _elements [ _position]
452
+ }
453
+
454
+ @_versioned
455
+ internal let _elements : Elements
456
+ @_versioned
457
+ internal var _position : Elements . Index
458
+ }
459
+
460
+ extension Unicode . DefaultScalarView : BidirectionalCollection {
461
+ @inline ( __always)
462
+ public func index( before i: Index ) -> Index {
463
+ var d = Encoding . ReverseDecoder ( )
464
+ var input = ReverseIndexingIterator (
465
+ _elements: codeUnits, _position: i. codeUnitIndex)
409
466
switch d. parseOne ( & input) {
410
467
case . valid( let scalarContent) :
411
468
return Index (
412
469
codeUnitIndex: codeUnits. index (
413
- i. codeUnitIndex, offsetBy: numericCast ( scalarContent. count) ) )
470
+ i. codeUnitIndex, offsetBy: - numericCast( scalarContent. count) ) )
414
471
case . invalid( let l) :
415
472
return Index (
416
473
codeUnitIndex: codeUnits. index (
417
- i. codeUnitIndex, offsetBy: numericCast ( l) ) )
474
+ i. codeUnitIndex, offsetBy: - numericCast( l) ) )
418
475
case . emptyInput:
419
- fatalError ( " advancing past endIndex " )
476
+ fatalError ( " indexing past startIndex " )
420
477
}
421
478
}
422
479
}
@@ -793,8 +850,9 @@ func checkDecodeUTF8(
793
850
}
794
851
}
795
852
796
- let scalars = Unicode . DefaultScalarView < [ UInt8 ] , UTF8 > ( codeUnits : utf8Str )
853
+ let scalars = Unicode . DefaultScalarView ( utf8Str , fromEncoding : UTF8 . self )
797
854
expectEqualSequence ( expected, scalars)
855
+ expectEqualSequence ( expected. reversed ( ) , scalars. reversed ( ) )
798
856
799
857
do {
800
858
var x = scalars. makeIterator ( )
@@ -2435,16 +2493,23 @@ public func run_UTF8Decode(_ N: Int) {
2435
2493
typealias D = UTF8 . ReverseDecoder
2436
2494
D . decode ( & it, repairingIllFormedSequences: true ) { total = total &+ $0. value }
2437
2495
#elseif SEQUENCE
2438
- for s in Unicode . DefaultScalarView < [ UInt8 ] , UTF8 > ( codeUnits : string ) {
2496
+ for s in Unicode . DefaultScalarView ( string , fromEncoding : UTF8 . self ) {
2439
2497
total = total &+ s. value
2440
2498
}
2441
2499
#elseif COLLECTION
2442
- let scalars = Unicode . DefaultScalarView < [ UInt8 ] , UTF8 > ( codeUnits : string )
2500
+ let scalars = Unicode . DefaultScalarView ( string , fromEncoding : UTF8 . self )
2443
2501
var i = scalars. startIndex
2444
2502
while i != scalars. endIndex {
2445
2503
total = total &+ scalars [ i] . value
2446
2504
i = scalars. index ( after: i)
2447
2505
}
2506
+ #elseif REVERSE_COLLECTION
2507
+ let scalars = Unicode . DefaultScalarView ( string, fromEncoding: UTF8 . self)
2508
+ var i = scalars. endIndex
2509
+ while i != scalars. startIndex {
2510
+ i = scalars. index ( before: i)
2511
+ total = total &+ scalars [ i] . value
2512
+ }
2448
2513
#else
2449
2514
Error_Unknown_Benchmark ( )
2450
2515
#endif
0 commit comments