302302use clone:: Clone ;
303303use cmp;
304304use fmt;
305+ use iter_private:: TrustedRandomAccess ;
305306use ops:: FnMut ;
306307use option:: Option :: { self , Some , None } ;
307308use usize;
@@ -622,7 +623,9 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
622623#[ stable( feature = "rust1" , since = "1.0.0" ) ]
623624pub struct Zip < A , B > {
624625 a : A ,
625- b : B
626+ b : B ,
627+ index : usize ,
628+ len : usize ,
626629}
627630
628631#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -631,29 +634,13 @@ impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator
631634 type Item = ( A :: Item , B :: Item ) ;
632635
633636 #[ inline]
634- fn next ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
635- self . a . next ( ) . and_then ( |x| {
636- self . b . next ( ) . and_then ( |y| {
637- Some ( ( x, y) )
638- } )
639- } )
637+ fn next ( & mut self ) -> Option < Self :: Item > {
638+ ZipImpl :: next ( self )
640639 }
641640
642641 #[ inline]
643642 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
644- let ( a_lower, a_upper) = self . a . size_hint ( ) ;
645- let ( b_lower, b_upper) = self . b . size_hint ( ) ;
646-
647- let lower = cmp:: min ( a_lower, b_lower) ;
648-
649- let upper = match ( a_upper, b_upper) {
650- ( Some ( x) , Some ( y) ) => Some ( cmp:: min ( x, y) ) ,
651- ( Some ( x) , None ) => Some ( x) ,
652- ( None , Some ( y) ) => Some ( y) ,
653- ( None , None ) => None
654- } ;
655-
656- ( lower, upper)
643+ ZipImpl :: size_hint ( self )
657644 }
658645}
659646
@@ -664,6 +651,51 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
664651{
665652 #[ inline]
666653 fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
654+ ZipImpl :: next_back ( self )
655+ }
656+ }
657+
658+ // Zip specialization trait
659+ #[ doc( hidden) ]
660+ trait ZipImpl < A , B > {
661+ type Item ;
662+ fn new ( a : A , b : B ) -> Self ;
663+ fn next ( & mut self ) -> Option < Self :: Item > ;
664+ fn size_hint ( & self ) -> ( usize , Option < usize > ) ;
665+ fn next_back ( & mut self ) -> Option < Self :: Item >
666+ where A : DoubleEndedIterator + ExactSizeIterator ,
667+ B : DoubleEndedIterator + ExactSizeIterator ;
668+ }
669+
670+ // General Zip impl
671+ #[ doc( hidden) ]
672+ impl < A , B > ZipImpl < A , B > for Zip < A , B >
673+ where A : Iterator , B : Iterator
674+ {
675+ type Item = ( A :: Item , B :: Item ) ;
676+ default fn new ( a : A , b : B ) -> Self {
677+ Zip {
678+ a : a,
679+ b : b,
680+ index : 0 , // not used in general case
681+ len : 0 ,
682+ }
683+ }
684+
685+ #[ inline]
686+ default fn next ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
687+ self . a . next ( ) . and_then ( |x| {
688+ self . b . next ( ) . and_then ( |y| {
689+ Some ( ( x, y) )
690+ } )
691+ } )
692+ }
693+
694+ #[ inline]
695+ default fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) >
696+ where A : DoubleEndedIterator + ExactSizeIterator ,
697+ B : DoubleEndedIterator + ExactSizeIterator
698+ {
667699 let a_sz = self . a . len ( ) ;
668700 let b_sz = self . b . len ( ) ;
669701 if a_sz != b_sz {
@@ -680,6 +712,73 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
680712 _ => unreachable ! ( ) ,
681713 }
682714 }
715+
716+ #[ inline]
717+ default fn size_hint ( & self ) -> ( usize , Option < usize > ) {
718+ let ( a_lower, a_upper) = self . a . size_hint ( ) ;
719+ let ( b_lower, b_upper) = self . b . size_hint ( ) ;
720+
721+ let lower = cmp:: min ( a_lower, b_lower) ;
722+
723+ let upper = match ( a_upper, b_upper) {
724+ ( Some ( x) , Some ( y) ) => Some ( cmp:: min ( x, y) ) ,
725+ ( Some ( x) , None ) => Some ( x) ,
726+ ( None , Some ( y) ) => Some ( y) ,
727+ ( None , None ) => None
728+ } ;
729+
730+ ( lower, upper)
731+ }
732+ }
733+
734+ #[ doc( hidden) ]
735+ impl < A , B > ZipImpl < A , B > for Zip < A , B >
736+ where A : TrustedRandomAccess , B : TrustedRandomAccess
737+ {
738+ fn new ( a : A , b : B ) -> Self {
739+ let len = cmp:: min ( a. len ( ) , b. len ( ) ) ;
740+ Zip {
741+ a : a,
742+ b : b,
743+ index : 0 ,
744+ len : len,
745+ }
746+ }
747+
748+ #[ inline]
749+ fn next ( & mut self ) -> Option < ( A :: Item , B :: Item ) > {
750+ if self . index < self . len {
751+ let i = self . index ;
752+ self . index += 1 ;
753+ unsafe {
754+ Some ( ( self . a . get_unchecked ( i) , self . b . get_unchecked ( i) ) )
755+ }
756+ } else {
757+ None
758+ }
759+ }
760+
761+ #[ inline]
762+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
763+ let len = self . len - self . index ;
764+ ( len, Some ( len) )
765+ }
766+
767+ #[ inline]
768+ fn next_back ( & mut self ) -> Option < ( A :: Item , B :: Item ) >
769+ where A : DoubleEndedIterator + ExactSizeIterator ,
770+ B : DoubleEndedIterator + ExactSizeIterator
771+ {
772+ if self . index < self . len {
773+ self . len -= 1 ;
774+ let i = self . len ;
775+ unsafe {
776+ Some ( ( self . a . get_unchecked ( i) , self . b . get_unchecked ( i) ) )
777+ }
778+ } else {
779+ None
780+ }
781+ }
683782}
684783
685784#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments