@@ -42,7 +42,7 @@ use crate::ascii;
4242use crate :: error:: Error ;
4343use crate :: escape;
4444use crate :: fmt:: { self , Write } ;
45- use crate :: iter:: FusedIterator ;
45+ use crate :: iter:: { FusedIterator , TrustedLen , TrustedRandomAccess , TrustedRandomAccessNoCoerce } ;
4646use crate :: num:: NonZero ;
4747
4848pub ( crate ) use self :: methods:: EscapeDebugExtArgs ;
@@ -373,176 +373,229 @@ impl fmt::Display for EscapeDebug {
373373 }
374374}
375375
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+ }
385389
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+ }
396393
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+ }
403400
404- #[ stable( feature = "fused" , since = "1.26.0" ) ]
405- impl FusedIterator for ToLowercase { }
401+ fn count( self ) -> usize {
402+ self . 0 . count( )
403+ }
406404
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+ }
409408
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+ }
419412
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+ }
430418
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+ }
435473 }
436474}
437475
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+ }
440485
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+ }
443495
444496#[ derive( Debug , Clone ) ]
445- enum CaseMappingIter {
446- Zero ,
447- One ( char ) ,
448- Two ( [ char ; 2 ] ) ,
449- Three ( [ char ; 3 ] ) ,
450- }
497+ struct CaseMappingIter ( core:: array:: IntoIter < char , 3 > ) ;
451498
452499impl CaseMappingIter {
500+ #[ inline]
453501 fn new ( chars : [ char ; 3 ] ) -> CaseMappingIter {
502+ let mut iter = chars. into_iter ( ) ;
454503 if chars[ 2 ] == '\0' {
504+ iter. next_back ( ) ;
455505 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
459510 }
460- } else {
461- CaseMappingIter :: Three ( [ chars[ 0 ] , chars[ 1 ] , chars[ 2 ] ] )
462511 }
512+ CaseMappingIter ( iter)
463513 }
464514}
465515
466516impl Iterator for CaseMappingIter {
467517 type Item = char ;
518+
468519 fn next ( & mut self ) -> Option < char > {
469- match * self {
470- CaseMappingIter :: Zero => None ,
471- CaseMappingIter :: One ( c) => {
472- * self = CaseMappingIter :: Zero ;
473- Some ( c)
474- }
475- CaseMappingIter :: Two ( [ b, c] ) => {
476- * self = CaseMappingIter :: One ( c) ;
477- Some ( b)
478- }
479- CaseMappingIter :: Three ( [ a, b, c] ) => {
480- * self = CaseMappingIter :: Two ( [ b, c] ) ;
481- Some ( a)
482- }
483- }
520+ self . 0 . next ( )
484521 }
485522
486523 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
487- let size = match self {
488- CaseMappingIter :: Zero => 0 ,
489- CaseMappingIter :: One ( _) => 1 ,
490- CaseMappingIter :: Two ( ..) => 2 ,
491- CaseMappingIter :: Three ( ..) => 3 ,
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) }
494549 }
495550}
496551
497552impl DoubleEndedIterator for CaseMappingIter {
498553 fn next_back ( & mut self ) -> Option < char > {
499- match * self {
500- CaseMappingIter :: Zero => None ,
501- CaseMappingIter :: One ( c) => {
502- * self = CaseMappingIter :: Zero ;
503- Some ( c)
504- }
505- CaseMappingIter :: Two ( [ b, c] ) => {
506- * self = CaseMappingIter :: One ( b) ;
507- Some ( c)
508- }
509- CaseMappingIter :: Three ( [ a, b, c] ) => {
510- * self = CaseMappingIter :: Two ( [ a, b] ) ;
511- Some ( c)
512- }
513- }
554+ self . 0 . next_back ( )
514555 }
515- }
516556
517- impl fmt:: Display for CaseMappingIter {
518- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
519- match * self {
520- CaseMappingIter :: Zero => Ok ( ( ) ) ,
521- CaseMappingIter :: One ( c) => f. write_char ( c) ,
522- CaseMappingIter :: Two ( [ b, c] ) => {
523- f. write_char ( b) ?;
524- f. write_char ( c)
525- }
526- CaseMappingIter :: Three ( [ a, b, c] ) => {
527- f. write_char ( a) ?;
528- f. write_char ( b) ?;
529- f. write_char ( c)
530- }
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)
532566 }
533567}
534568
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 ( )
539576 }
540577}
541578
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]
544594 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 ( ( ) )
546599 }
547600}
548601
0 commit comments