@@ -64,6 +64,7 @@ use num::{ToPrimitive, Int};
64
64
use ops:: { Add , Deref } ;
65
65
use option:: { Option , Some , None } ;
66
66
use uint;
67
+ use self :: EitherOrBoth :: { Left , Right , Both } ;
67
68
68
69
#[ deprecated = "renamed to Extend" ] pub use self :: Extend as Extendable ;
69
70
@@ -802,7 +803,7 @@ impl<'a, A, B, T: ExactSizeIterator<A>> ExactSizeIterator<B> for Map<'a, A, B, T
802
803
impl < A , B , T , U > ExactSizeIterator < ( A , B ) > for Zip < T , U >
803
804
where T : ExactSizeIterator < A > , U : ExactSizeIterator < B > { }
804
805
#[ 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 >
806
807
where T : ExactSizeIterator < A > , U : ExactSizeIterator < B > { }
807
808
808
809
/// An double-ended iterator with the direction inverted
@@ -1400,12 +1401,14 @@ pub struct ZipLongest<T, U> {
1400
1401
b : U
1401
1402
}
1402
1403
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 > {
1404
1405
#[ inline]
1405
- fn next ( & mut self ) -> Option < ( Option < A > , Option < B > ) > {
1406
+ fn next ( & mut self ) -> Option < EitherOrBoth < A , B > > {
1406
1407
match ( self . a . next ( ) , self . b . next ( ) ) {
1407
1408
( 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) ) ,
1409
1412
}
1410
1413
}
1411
1414
@@ -1425,36 +1428,56 @@ impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(Option<A>, Option<B>)> for
1425
1428
}
1426
1429
}
1427
1430
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 > >
1429
1432
for ZipLongest < T , U > {
1430
1433
#[ inline]
1431
- fn next_back ( & mut self ) -> Option < ( Option < A > , Option < B > ) > {
1434
+ fn next_back ( & mut self ) -> Option < EitherOrBoth < A , B > > {
1432
1435
use cmp:: { Equal , Greater , Less } ;
1433
1436
match self . a . len ( ) . cmp ( & self . b . len ( ) ) {
1434
1437
Equal => match ( self . a . next_back ( ) , self . b . next_back ( ) ) {
1435
1438
( 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) ) ,
1437
1443
} ,
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 ) ,
1440
1446
}
1441
1447
}
1442
1448
}
1443
1449
1444
1450
impl < 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 > {
1446
1452
#[ inline]
1447
1453
fn indexable ( & self ) -> uint {
1448
1454
cmp:: max ( self . a . indexable ( ) , self . b . indexable ( ) )
1449
1455
}
1450
1456
1451
1457
#[ inline]
1452
- fn idx ( & mut self , index : uint ) -> Option < ( Option < A > , Option < B > ) > {
1458
+ fn idx ( & mut self , index : uint ) -> Option < EitherOrBoth < A , B > > {
1453
1459
match ( self . a . idx ( index) , self . b . idx ( index) ) {
1454
1460
( 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 ) ,
1458
1481
}
1459
1482
1460
1483
/// An iterator which maps the values of `iter` with `f`
0 commit comments