@@ -42,7 +42,7 @@ use crate::ascii;
42
42
use crate :: error:: Error ;
43
43
use crate :: escape;
44
44
use crate :: fmt:: { self , Write } ;
45
- use crate :: iter:: FusedIterator ;
45
+ use crate :: iter:: { FusedIterator , TrustedLen , TrustedRandomAccess , TrustedRandomAccessNoCoerce } ;
46
46
use crate :: num:: NonZero ;
47
47
48
48
pub ( crate ) use self :: methods:: EscapeDebugExtArgs ;
@@ -373,176 +373,229 @@ impl fmt::Display for EscapeDebug {
373
373
}
374
374
}
375
375
376
- /// Returns an iterator that yields the lowercase equivalent of a `char`.
377
- ///
378
- /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See
379
- /// its documentation for more.
380
- ///
381
- /// [`to_lowercase`]: char::to_lowercase
382
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
383
- #[ derive( Debug , Clone ) ]
384
- pub struct ToLowercase ( CaseMappingIter ) ;
376
+ macro_rules! casemappingiter_impls {
377
+ ( $( #[ $attr: meta] ) * $ITER_NAME: ident) => {
378
+ $( #[ $attr] ) *
379
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
380
+ #[ derive( Debug , Clone ) ]
381
+ pub struct $ITER_NAME( CaseMappingIter ) ;
382
+
383
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
384
+ impl Iterator for $ITER_NAME {
385
+ type Item = char ;
386
+ fn next( & mut self ) -> Option <char > {
387
+ self . 0 . next( )
388
+ }
385
389
386
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
387
- impl Iterator for ToLowercase {
388
- type Item = char ;
389
- fn next ( & mut self ) -> Option < char > {
390
- self . 0 . next ( )
391
- }
392
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
393
- self . 0 . size_hint ( )
394
- }
395
- }
390
+ fn size_hint( & self ) -> ( usize , Option <usize >) {
391
+ self . 0 . size_hint( )
392
+ }
396
393
397
- # [ stable ( feature = "case_mapping_double_ended" , since = "1.59.0" ) ]
398
- impl DoubleEndedIterator for ToLowercase {
399
- fn next_back ( & mut self ) -> Option < char > {
400
- self . 0 . next_back ( )
401
- }
402
- }
394
+ fn fold< Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
395
+ where
396
+ Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
397
+ {
398
+ self . 0 . fold ( init , fold )
399
+ }
403
400
404
- #[ stable( feature = "fused" , since = "1.26.0" ) ]
405
- impl FusedIterator for ToLowercase { }
401
+ fn count( self ) -> usize {
402
+ self . 0 . count( )
403
+ }
406
404
407
- #[ stable( feature = "exact_size_case_mapping_iter" , since = "1.35.0" ) ]
408
- impl ExactSizeIterator for ToLowercase { }
405
+ fn last( self ) -> Option <Self :: Item > {
406
+ self . 0 . last( )
407
+ }
409
408
410
- /// Returns an iterator that yields the uppercase equivalent of a `char`.
411
- ///
412
- /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
413
- /// its documentation for more.
414
- ///
415
- /// [`to_uppercase`]: char::to_uppercase
416
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
417
- #[ derive( Debug , Clone ) ]
418
- pub struct ToUppercase ( CaseMappingIter ) ;
409
+ fn advance_by( & mut self , n: usize ) -> Result <( ) , NonZero <usize >> {
410
+ self . 0 . advance_by( n)
411
+ }
419
412
420
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
421
- impl Iterator for ToUppercase {
422
- type Item = char ;
423
- fn next ( & mut self ) -> Option < char > {
424
- self . 0 . next ( )
425
- }
426
- fn size_hint ( & self ) -> ( usize , Option < usize > ) {
427
- self . 0 . size_hint ( )
428
- }
429
- }
413
+ unsafe fn __iterator_get_unchecked( & mut self , idx: usize ) -> Self :: Item {
414
+ // SAFETY: just forwarding requirements to caller
415
+ unsafe { self . 0.__ iterator_get_unchecked( idx) }
416
+ }
417
+ }
430
418
431
- #[ stable( feature = "case_mapping_double_ended" , since = "1.59.0" ) ]
432
- impl DoubleEndedIterator for ToUppercase {
433
- fn next_back ( & mut self ) -> Option < char > {
434
- self . 0 . next_back ( )
419
+ #[ stable( feature = "case_mapping_double_ended" , since = "1.59.0" ) ]
420
+ impl DoubleEndedIterator for $ITER_NAME {
421
+ fn next_back( & mut self ) -> Option <char > {
422
+ self . 0 . next_back( )
423
+ }
424
+
425
+ fn rfold<Acc , Fold >( self , init: Acc , rfold: Fold ) -> Acc
426
+ where
427
+ Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
428
+ {
429
+ self . 0 . rfold( init, rfold)
430
+ }
431
+
432
+ fn advance_back_by( & mut self , n: usize ) -> Result <( ) , NonZero <usize >> {
433
+ self . 0 . advance_back_by( n)
434
+ }
435
+ }
436
+
437
+ #[ stable( feature = "fused" , since = "1.26.0" ) ]
438
+ impl FusedIterator for $ITER_NAME { }
439
+
440
+ #[ stable( feature = "exact_size_case_mapping_iter" , since = "1.35.0" ) ]
441
+ impl ExactSizeIterator for $ITER_NAME {
442
+ fn len( & self ) -> usize {
443
+ self . 0 . len( )
444
+ }
445
+
446
+ fn is_empty( & self ) -> bool {
447
+ self . 0 . is_empty( )
448
+ }
449
+ }
450
+
451
+ // SAFETY: forwards to inner `array::IntoIter`
452
+ #[ unstable( feature = "trusted_len" , issue = "37572" ) ]
453
+ unsafe impl TrustedLen for $ITER_NAME { }
454
+
455
+ // SAFETY: forwards to inner `array::IntoIter`
456
+ #[ doc( hidden) ]
457
+ #[ unstable( feature = "std_internals" , issue = "none" ) ]
458
+ unsafe impl TrustedRandomAccessNoCoerce for $ITER_NAME {
459
+ const MAY_HAVE_SIDE_EFFECT : bool = false ;
460
+ }
461
+
462
+ // SAFETY: this iter has no subtypes/supertypes
463
+ #[ doc( hidden) ]
464
+ #[ unstable( feature = "std_internals" , issue = "none" ) ]
465
+ unsafe impl TrustedRandomAccess for $ITER_NAME { }
466
+
467
+ #[ stable( feature = "char_struct_display" , since = "1.16.0" ) ]
468
+ impl fmt:: Display for $ITER_NAME {
469
+ fn fmt( & self , f: & mut fmt:: Formatter <' _>) -> fmt:: Result {
470
+ fmt:: Display :: fmt( & self . 0 , f)
471
+ }
472
+ }
435
473
}
436
474
}
437
475
438
- #[ stable( feature = "fused" , since = "1.26.0" ) ]
439
- impl FusedIterator for ToUppercase { }
476
+ casemappingiter_impls ! {
477
+ /// Returns an iterator that yields the lowercase equivalent of a `char`.
478
+ ///
479
+ /// This `struct` is created by the [`to_lowercase`] method on [`char`]. See
480
+ /// its documentation for more.
481
+ ///
482
+ /// [`to_lowercase`]: char::to_lowercase
483
+ ToLowercase
484
+ }
440
485
441
- #[ stable( feature = "exact_size_case_mapping_iter" , since = "1.35.0" ) ]
442
- impl ExactSizeIterator for ToUppercase { }
486
+ casemappingiter_impls ! {
487
+ /// Returns an iterator that yields the uppercase equivalent of a `char`.
488
+ ///
489
+ /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See
490
+ /// its documentation for more.
491
+ ///
492
+ /// [`to_uppercase`]: char::to_uppercase
493
+ ToUppercase
494
+ }
443
495
444
496
#[ derive( Debug , Clone ) ]
445
- enum CaseMappingIter {
446
- Three ( char , char , char ) ,
447
- Two ( char , char ) ,
448
- One ( char ) ,
449
- Zero ,
450
- }
497
+ struct CaseMappingIter ( core:: array:: IntoIter < char , 3 > ) ;
451
498
452
499
impl CaseMappingIter {
500
+ #[ inline]
453
501
fn new ( chars : [ char ; 3 ] ) -> CaseMappingIter {
502
+ let mut iter = chars. into_iter ( ) ;
454
503
if chars[ 2 ] == '\0' {
504
+ iter. next_back ( ) ;
455
505
if chars[ 1 ] == '\0' {
456
- CaseMappingIter :: One ( chars[ 0 ] ) // Including if chars[0] == '\0'
457
- } else {
458
- CaseMappingIter :: Two ( chars[ 0 ] , chars[ 1 ] )
506
+ iter. next_back ( ) ;
507
+
508
+ // Deliberately don't check `chars[0]`,
509
+ // as '\0' lowercases to itself
459
510
}
460
- } else {
461
- CaseMappingIter :: Three ( chars[ 0 ] , chars[ 1 ] , chars[ 2 ] )
462
511
}
512
+ CaseMappingIter ( iter)
463
513
}
464
514
}
465
515
466
516
impl Iterator for CaseMappingIter {
467
517
type Item = char ;
518
+
468
519
fn next ( & mut self ) -> Option < char > {
469
- match * self {
470
- CaseMappingIter :: Three ( a, b, c) => {
471
- * self = CaseMappingIter :: Two ( b, c) ;
472
- Some ( a)
473
- }
474
- CaseMappingIter :: Two ( b, c) => {
475
- * self = CaseMappingIter :: One ( c) ;
476
- Some ( b)
477
- }
478
- CaseMappingIter :: One ( c) => {
479
- * self = CaseMappingIter :: Zero ;
480
- Some ( c)
481
- }
482
- CaseMappingIter :: Zero => None ,
483
- }
520
+ self . 0 . next ( )
484
521
}
485
522
486
523
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
487
- let size = match self {
488
- CaseMappingIter :: Three ( ..) => 3 ,
489
- CaseMappingIter :: Two ( ..) => 2 ,
490
- CaseMappingIter :: One ( _) => 1 ,
491
- CaseMappingIter :: Zero => 0 ,
492
- } ;
493
- ( size, Some ( size) )
524
+ self . 0 . size_hint ( )
525
+ }
526
+
527
+ fn fold < Acc , Fold > ( self , init : Acc , fold : Fold ) -> Acc
528
+ where
529
+ Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
530
+ {
531
+ self . 0 . fold ( init, fold)
532
+ }
533
+
534
+ fn count ( self ) -> usize {
535
+ self . 0 . count ( )
536
+ }
537
+
538
+ fn last ( self ) -> Option < Self :: Item > {
539
+ self . 0 . last ( )
540
+ }
541
+
542
+ fn advance_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
543
+ self . 0 . advance_by ( n)
544
+ }
545
+
546
+ unsafe fn __iterator_get_unchecked ( & mut self , idx : usize ) -> Self :: Item {
547
+ // SAFETY: just forwarding requirements to caller
548
+ unsafe { self . 0 . __iterator_get_unchecked ( idx) }
494
549
}
495
550
}
496
551
497
552
impl DoubleEndedIterator for CaseMappingIter {
498
553
fn next_back ( & mut self ) -> Option < char > {
499
- match * self {
500
- CaseMappingIter :: Three ( a, b, c) => {
501
- * self = CaseMappingIter :: Two ( a, b) ;
502
- Some ( c)
503
- }
504
- CaseMappingIter :: Two ( b, c) => {
505
- * self = CaseMappingIter :: One ( b) ;
506
- Some ( c)
507
- }
508
- CaseMappingIter :: One ( c) => {
509
- * self = CaseMappingIter :: Zero ;
510
- Some ( c)
511
- }
512
- CaseMappingIter :: Zero => None ,
513
- }
554
+ self . 0 . next_back ( )
514
555
}
515
- }
516
556
517
- impl fmt:: Display for CaseMappingIter {
518
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
519
- match * self {
520
- CaseMappingIter :: Three ( a, b, c) => {
521
- f. write_char ( a) ?;
522
- f. write_char ( b) ?;
523
- f. write_char ( c)
524
- }
525
- CaseMappingIter :: Two ( b, c) => {
526
- f. write_char ( b) ?;
527
- f. write_char ( c)
528
- }
529
- CaseMappingIter :: One ( c) => f. write_char ( c) ,
530
- CaseMappingIter :: Zero => Ok ( ( ) ) ,
531
- }
557
+ fn rfold < Acc , Fold > ( self , init : Acc , rfold : Fold ) -> Acc
558
+ where
559
+ Fold : FnMut ( Acc , Self :: Item ) -> Acc ,
560
+ {
561
+ self . 0 . rfold ( init, rfold)
562
+ }
563
+
564
+ fn advance_back_by ( & mut self , n : usize ) -> Result < ( ) , NonZero < usize > > {
565
+ self . 0 . advance_back_by ( n)
532
566
}
533
567
}
534
568
535
- #[ stable( feature = "char_struct_display" , since = "1.16.0" ) ]
536
- impl fmt:: Display for ToLowercase {
537
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
538
- fmt:: Display :: fmt ( & self . 0 , f)
569
+ impl ExactSizeIterator for CaseMappingIter {
570
+ fn len ( & self ) -> usize {
571
+ self . 0 . len ( )
572
+ }
573
+
574
+ fn is_empty ( & self ) -> bool {
575
+ self . 0 . is_empty ( )
539
576
}
540
577
}
541
578
542
- #[ stable( feature = "char_struct_display" , since = "1.16.0" ) ]
543
- impl fmt:: Display for ToUppercase {
579
+ impl FusedIterator for CaseMappingIter { }
580
+
581
+ // SAFETY: forwards to inner `array::IntoIter`
582
+ unsafe impl TrustedLen for CaseMappingIter { }
583
+
584
+ // SAFETY: forwards to inner `array::IntoIter`
585
+ unsafe impl TrustedRandomAccessNoCoerce for CaseMappingIter {
586
+ const MAY_HAVE_SIDE_EFFECT : bool = false ;
587
+ }
588
+
589
+ // SAFETY: `CaseMappingIter` has no subtypes/supertypes
590
+ unsafe impl TrustedRandomAccess for CaseMappingIter { }
591
+
592
+ impl fmt:: Display for CaseMappingIter {
593
+ #[ inline]
544
594
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
545
- fmt:: Display :: fmt ( & self . 0 , f)
595
+ for c in self . 0 . clone ( ) {
596
+ f. write_char ( c) ?;
597
+ }
598
+ Ok ( ( ) )
546
599
}
547
600
}
548
601
0 commit comments