302
302
use clone:: Clone ;
303
303
use cmp;
304
304
use fmt;
305
+ use iter_private:: TrustedRandomAccess ;
305
306
use ops:: FnMut ;
306
307
use option:: Option :: { self , Some , None } ;
307
308
use usize;
@@ -622,7 +623,9 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
622
623
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
623
624
pub struct Zip < A , B > {
624
625
a : A ,
625
- b : B
626
+ b : B ,
627
+ index : usize ,
628
+ len : usize ,
626
629
}
627
630
628
631
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -631,29 +634,13 @@ impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator
631
634
type Item = ( A :: Item , B :: Item ) ;
632
635
633
636
#[ 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 )
640
639
}
641
640
642
641
#[ inline]
643
642
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 )
657
644
}
658
645
}
659
646
@@ -664,6 +651,51 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
664
651
{
665
652
#[ inline]
666
653
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
+ {
667
699
let a_sz = self . a . len ( ) ;
668
700
let b_sz = self . b . len ( ) ;
669
701
if a_sz != b_sz {
@@ -680,6 +712,73 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
680
712
_ => unreachable ! ( ) ,
681
713
}
682
714
}
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
+ }
683
782
}
684
783
685
784
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments