@@ -64,6 +64,7 @@ use num::{ToPrimitive, Int};
6464use ops:: { Add , Deref } ;
6565use option:: { Option , Some , None } ;
6666use uint;
67+ use self :: EitherOrBoth :: { Left , Right , Both } ;
6768
6869#[ deprecated = "renamed to Extend" ] pub use self :: Extend as Extendable ;
6970
@@ -802,7 +803,7 @@ impl<'a, A, B, T: ExactSizeIterator<A>> ExactSizeIterator<B> for Map<'a, A, B, T
802803impl < A , B , T , U > ExactSizeIterator < ( A , B ) > for Zip < T , U >
803804 where T : ExactSizeIterator < A > , U : ExactSizeIterator < B > { }
804805#[ unstable = "trait is unstable" ]
805- impl < A , B , T , U > ExactSizeIterator < ( Option < A > , Option < B > ) > for ZipLongest < T , U >
806+ impl < A , B , T , U > ExactSizeIterator < EitherOrBoth < A , B > > for ZipLongest < T , U >
806807 where T : ExactSizeIterator < A > , U : ExactSizeIterator < B > { }
807808
808809/// An double-ended iterator with the direction inverted
@@ -1400,12 +1401,14 @@ pub struct ZipLongest<T, U> {
14001401 b : U
14011402}
14021403
1403- impl < A , B , T : Iterator < A > , U : Iterator < B > > Iterator < ( Option < A > , Option < B > ) > for ZipLongest < T , U > {
1404+ impl < A , B , T : Iterator < A > , U : Iterator < B > > Iterator < EitherOrBoth < A , B > > for ZipLongest < T , U > {
14041405 #[ inline]
1405- fn next ( & mut self ) -> Option < ( Option < A > , Option < B > ) > {
1406+ fn next ( & mut self ) -> Option < EitherOrBoth < A , B > > {
14061407 match ( self . a . next ( ) , self . b . next ( ) ) {
14071408 ( None , None ) => None ,
1408- pair_of_options => Some ( pair_of_options) ,
1409+ ( Some ( a) , None ) => Some ( Left ( a) ) ,
1410+ ( None , Some ( b) ) => Some ( Right ( b) ) ,
1411+ ( Some ( a) , Some ( b) ) => Some ( Both ( a, b) ) ,
14091412 }
14101413 }
14111414
@@ -1425,36 +1428,56 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(Option<A>, Option<B>)> for
14251428 }
14261429}
14271430
1428- impl < A , B , T : ExactSize < A > , U : ExactSize < B > > DoubleEndedIterator < ( Option < A > , Option < B > ) >
1431+ impl < A , B , T : ExactSizeIterator < A > , U : ExactSizeIterator < B > > DoubleEndedIterator < EitherOrBoth < A , B > >
14291432for ZipLongest < T , U > {
14301433 #[ inline]
1431- fn next_back ( & mut self ) -> Option < ( Option < A > , Option < B > ) > {
1434+ fn next_back ( & mut self ) -> Option < EitherOrBoth < A , B > > {
14321435 use cmp:: { Equal , Greater , Less } ;
14331436 match self . a . len ( ) . cmp ( & self . b . len ( ) ) {
14341437 Equal => match ( self . a . next_back ( ) , self . b . next_back ( ) ) {
14351438 ( None , None ) => None ,
1436- pair_of_options => Some ( pair_of_options) ,
1439+ ( Some ( a) , Some ( b) ) => Some ( Both ( a, b) ) ,
1440+ // These can only happen if .len() is inconsistent with .next_back()
1441+ ( Some ( a) , None ) => Some ( Left ( a) ) ,
1442+ ( None , Some ( b) ) => Some ( Right ( b) ) ,
14371443 } ,
1438- Greater => self . a . next_back ( ) . map ( |x| ( Some ( x ) , None ) ) ,
1439- Less => self . b . next_back ( ) . map ( |y| ( None , Some ( y ) ) ) ,
1444+ Greater => self . a . next_back ( ) . map ( Left ) ,
1445+ Less => self . b . next_back ( ) . map ( Right ) ,
14401446 }
14411447 }
14421448}
14431449
14441450impl < A , B , T : RandomAccessIterator < A > , U : RandomAccessIterator < B > >
1445- RandomAccessIterator < ( Option < A > , Option < B > ) > for ZipLongest < T , U > {
1451+ RandomAccessIterator < EitherOrBoth < A , B > > for ZipLongest < T , U > {
14461452 #[ inline]
14471453 fn indexable ( & self ) -> uint {
14481454 cmp:: max ( self . a . indexable ( ) , self . b . indexable ( ) )
14491455 }
14501456
14511457 #[ inline]
1452- fn idx ( & mut self , index : uint ) -> Option < ( Option < A > , Option < B > ) > {
1458+ fn idx ( & mut self , index : uint ) -> Option < EitherOrBoth < A , B > > {
14531459 match ( self . a . idx ( index) , self . b . idx ( index) ) {
14541460 ( None , None ) => None ,
1455- pair_of_options => Some ( pair_of_options) ,
1456- }
1457- }
1461+ ( Some ( a) , None ) => Some ( Left ( a) ) ,
1462+ ( None , Some ( b) ) => Some ( Right ( b) ) ,
1463+ ( Some ( a) , Some ( b) ) => Some ( Both ( a, b) ) ,
1464+ }
1465+ }
1466+ }
1467+
1468+ /// A value yielded by `ZipLongest`.
1469+ /// Contains one or two values,
1470+ /// depending on which of the input iterators are exhausted.
1471+ #[ deriving( Clone , PartialEq , Eq , Show ) ]
1472+ pub enum EitherOrBoth < A , B > {
1473+ /// Neither input iterator is exhausted yet, yielding two values.
1474+ Both ( A , B ) ,
1475+ /// The parameter iterator of `.zip_longest()` is exhausted,
1476+ /// only yielding a value from the `self` iterator.
1477+ Left ( A ) ,
1478+ /// The `self` iterator of `.zip_longest()` is exhausted,
1479+ /// only yielding a value from the parameter iterator.
1480+ Right ( B ) ,
14581481}
14591482
14601483/// An iterator which maps the values of `iter` with `f`
0 commit comments