@@ -137,7 +137,7 @@ pub trait IteratorExt<A>: Iterator<A> {
137137 ///
138138 /// ```rust
139139 /// let a = [0i];
140- /// let b = [1i];
140+ /// let b = [1i, 2i ];
141141 /// let mut it = a.iter().zip(b.iter());
142142 /// let (x0, x1) = (0i, 1i);
143143 /// assert_eq!(it.next().unwrap(), (&x0, &x1));
@@ -149,6 +149,27 @@ pub trait IteratorExt<A>: Iterator<A> {
149149 Zip { a : self , b : other}
150150 }
151151
152+ /// Creates an iterator which iterates over both this and the specified
153+ /// iterators simultaneously, yielding pairs of two optional elements.
154+ /// When both iterators return None, all further invocations of next() will
155+ /// return None.
156+ ///
157+ /// # Example
158+ ///
159+ /// ```rust
160+ /// let a = [0i];
161+ /// let b = [1i, 2i];
162+ /// let mut it = a.iter().zip(b.iter());
163+ /// let (x0, x1, x2) = (0i, 1i, 2i);
164+ /// assert_eq!(it.next().unwrap(), (Some(&x0), Some(&x1)));
165+ /// assert_eq!(it.next().unwrap(), (None, Some(&x2)));
166+ /// assert!(it.next().is_none());
167+ /// ```
168+ #[ inline]
169+ fn zip_longest < B , U : Iterator < B > > ( self , other : U ) -> ZipLongest < Self , U > {
170+ ZipLongest { a : self , b : other}
171+ }
172+
152173 /// Creates a new iterator which will apply the specified function to each
153174 /// element returned by the first, yielding the mapped element instead.
154175 ///
@@ -780,6 +801,9 @@ impl<'a, A, B, T: ExactSizeIterator<A>> ExactSizeIterator<B> for Map<'a, A, B, T
780801#[ unstable = "trait is unstable" ]
781802impl < A , B , T , U > ExactSizeIterator < ( A , B ) > for Zip < T , U >
782803 where T : ExactSizeIterator < A > , U : ExactSizeIterator < B > { }
804+ #[ unstable = "trait is unstable" ]
805+ impl < A , B , T , U > ExactSizeIterator < ( Option < A > , Option < B > ) > for ZipLongest < T , U >
806+ where T : ExactSizeIterator < A > , U : ExactSizeIterator < B > { }
783807
784808/// An double-ended iterator with the direction inverted
785809#[ deriving( Clone ) ]
@@ -1368,6 +1392,71 @@ RandomAccessIterator<(A, B)> for Zip<T, U> {
13681392 }
13691393}
13701394
1395+ /// An iterator which iterates two other iterators simultaneously
1396+ #[ deriving( Clone ) ]
1397+ #[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
1398+ pub struct ZipLongest < T , U > {
1399+ a : T ,
1400+ b : U
1401+ }
1402+
1403+ impl < A , B , T : Iterator < A > , U : Iterator < B > > Iterator < ( Option < A > , Option < B > ) > for ZipLongest < T , U > {
1404+ #[ inline]
1405+ fn next ( & mut self ) -> Option < ( Option < A > , Option < B > ) > {
1406+ match ( self . a . next ( ) , self . b . next ( ) ) {
1407+ ( None , None ) => None ,
1408+ pair_of_options => Some ( pair_of_options) ,
1409+ }
1410+ }
1411+
1412+ #[ inline]
1413+ fn size_hint ( & self ) -> ( uint , Option < uint > ) {
1414+ let ( a_lower, a_upper) = self . a . size_hint ( ) ;
1415+ let ( b_lower, b_upper) = self . b . size_hint ( ) ;
1416+
1417+ let lower = cmp:: max ( a_lower, b_lower) ;
1418+
1419+ let upper = match ( a_upper, b_upper) {
1420+ ( Some ( x) , Some ( y) ) => Some ( cmp:: max ( x, y) ) ,
1421+ _ => None
1422+ } ;
1423+
1424+ ( lower, upper)
1425+ }
1426+ }
1427+
1428+ impl < A , B , T : ExactSize < A > , U : ExactSize < B > > DoubleEndedIterator < ( Option < A > , Option < B > ) >
1429+ for ZipLongest < T , U > {
1430+ #[ inline]
1431+ fn next_back ( & mut self ) -> Option < ( Option < A > , Option < B > ) > {
1432+ use cmp:: { Equal , Greater , Less } ;
1433+ match self . a . len ( ) . cmp ( & self . b . len ( ) ) {
1434+ Equal => match ( self . a . next_back ( ) , self . b . next_back ( ) ) {
1435+ ( None , None ) => None ,
1436+ pair_of_options => Some ( pair_of_options) ,
1437+ } ,
1438+ Greater => self . a . next_back ( ) . map ( |x| ( Some ( x) , None ) ) ,
1439+ Less => self . b . next_back ( ) . map ( |y| ( None , Some ( y) ) ) ,
1440+ }
1441+ }
1442+ }
1443+
1444+ impl < A , B , T : RandomAccessIterator < A > , U : RandomAccessIterator < B > >
1445+ RandomAccessIterator < ( Option < A > , Option < B > ) > for ZipLongest < T , U > {
1446+ #[ inline]
1447+ fn indexable ( & self ) -> uint {
1448+ cmp:: max ( self . a . indexable ( ) , self . b . indexable ( ) )
1449+ }
1450+
1451+ #[ inline]
1452+ fn idx ( & mut self , index : uint ) -> Option < ( Option < A > , Option < B > ) > {
1453+ match ( self . a . idx ( index) , self . b . idx ( index) ) {
1454+ ( None , None ) => None ,
1455+ pair_of_options => Some ( pair_of_options) ,
1456+ }
1457+ }
1458+ }
1459+
13711460/// An iterator which maps the values of `iter` with `f`
13721461#[ must_use = "iterator adaptors are lazy and do nothing unless consumed" ]
13731462#[ stable]
0 commit comments