@@ -411,14 +411,17 @@ pub struct EscapeUnicode {
411
411
hex_digit_idx : usize ,
412
412
}
413
413
414
+ // The enum values are ordered so that their representation is the
415
+ // same as the remaining length (besides the hexadecimal digits). This
416
+ // likely makes `len()` a single load from memory) and inline-worth.
414
417
#[ derive( Clone , Debug ) ]
415
418
enum EscapeUnicodeState {
416
- Backslash ,
417
- Type ,
418
- LeftBrace ,
419
- Value ,
420
- RightBrace ,
421
419
Done ,
420
+ RightBrace ,
421
+ Value ,
422
+ LeftBrace ,
423
+ Type ,
424
+ Backslash ,
422
425
}
423
426
424
427
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -457,19 +460,17 @@ impl Iterator for EscapeUnicode {
457
460
}
458
461
}
459
462
463
+ #[ inline]
460
464
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
461
- let n = match self . state {
462
- EscapeUnicodeState :: Backslash => 5 ,
463
- EscapeUnicodeState :: Type => 4 ,
464
- EscapeUnicodeState :: LeftBrace => 3 ,
465
- EscapeUnicodeState :: Value => 2 ,
466
- EscapeUnicodeState :: RightBrace => 1 ,
467
- EscapeUnicodeState :: Done => 0 ,
468
- } ;
469
- let n = n + self . hex_digit_idx ;
465
+ let n = self . len ( ) ;
470
466
( n, Some ( n) )
471
467
}
472
468
469
+ #[ inline]
470
+ fn count ( self ) -> usize {
471
+ self . len ( )
472
+ }
473
+
473
474
fn last ( self ) -> Option < char > {
474
475
match self . state {
475
476
EscapeUnicodeState :: Done => None ,
@@ -483,6 +484,22 @@ impl Iterator for EscapeUnicode {
483
484
}
484
485
}
485
486
487
+ #[ stable( feature = "exact_size_escape" , since = "1.11.0" ) ]
488
+ impl ExactSizeIterator for EscapeUnicode {
489
+ #[ inline]
490
+ fn len ( & self ) -> usize {
491
+ // The match is a single memory access with no branching
492
+ self . hex_digit_idx + match self . state {
493
+ EscapeUnicodeState :: Done => 0 ,
494
+ EscapeUnicodeState :: RightBrace => 1 ,
495
+ EscapeUnicodeState :: Value => 2 ,
496
+ EscapeUnicodeState :: LeftBrace => 3 ,
497
+ EscapeUnicodeState :: Type => 4 ,
498
+ EscapeUnicodeState :: Backslash => 5 ,
499
+ }
500
+ }
501
+ }
502
+
486
503
/// An iterator that yields the literal escape code of a `char`.
487
504
///
488
505
/// This `struct` is created by the [`escape_default()`] method on [`char`]. See
@@ -498,9 +515,9 @@ pub struct EscapeDefault {
498
515
499
516
#[ derive( Clone , Debug ) ]
500
517
enum EscapeDefaultState {
501
- Backslash ( char ) ,
502
- Char ( char ) ,
503
518
Done ,
519
+ Char ( char ) ,
520
+ Backslash ( char ) ,
504
521
Unicode ( EscapeUnicode ) ,
505
522
}
506
523
@@ -523,22 +540,15 @@ impl Iterator for EscapeDefault {
523
540
}
524
541
}
525
542
543
+ #[ inline]
526
544
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
527
- match self . state {
528
- EscapeDefaultState :: Char ( _) => ( 1 , Some ( 1 ) ) ,
529
- EscapeDefaultState :: Backslash ( _) => ( 2 , Some ( 2 ) ) ,
530
- EscapeDefaultState :: Unicode ( ref iter) => iter. size_hint ( ) ,
531
- EscapeDefaultState :: Done => ( 0 , Some ( 0 ) ) ,
532
- }
545
+ let n = self . len ( ) ;
546
+ ( n, Some ( n) )
533
547
}
534
548
549
+ #[ inline]
535
550
fn count ( self ) -> usize {
536
- match self . state {
537
- EscapeDefaultState :: Char ( _) => 1 ,
538
- EscapeDefaultState :: Unicode ( iter) => iter. count ( ) ,
539
- EscapeDefaultState :: Done => 0 ,
540
- EscapeDefaultState :: Backslash ( _) => 2 ,
541
- }
551
+ self . len ( )
542
552
}
543
553
544
554
fn nth ( & mut self , n : usize ) -> Option < char > {
@@ -578,6 +588,18 @@ impl Iterator for EscapeDefault {
578
588
}
579
589
}
580
590
591
+ #[ stable( feature = "exact_size_escape" , since = "1.11.0" ) ]
592
+ impl ExactSizeIterator for EscapeDefault {
593
+ fn len ( & self ) -> usize {
594
+ match self . state {
595
+ EscapeDefaultState :: Done => 0 ,
596
+ EscapeDefaultState :: Char ( _) => 1 ,
597
+ EscapeDefaultState :: Backslash ( _) => 2 ,
598
+ EscapeDefaultState :: Unicode ( ref iter) => iter. len ( ) ,
599
+ }
600
+ }
601
+ }
602
+
581
603
/// An iterator over `u8` entries represending the UTF-8 encoding of a `char`
582
604
/// value.
583
605
///
0 commit comments