99// except according to those terms.
1010
1111use cmp:: Ordering ;
12+ use ops:: Try ;
1213
14+ use super :: { AlwaysOk , LoopState } ;
1315use super :: { Chain , Cycle , Cloned , Enumerate , Filter , FilterMap , FlatMap , Fuse } ;
1416use super :: { Inspect , Map , Peekable , Scan , Skip , SkipWhile , StepBy , Take , TakeWhile , Rev } ;
1517use super :: { Zip , Sum , Product } ;
@@ -251,12 +253,8 @@ pub trait Iterator {
251253 /// ```
252254 #[ inline]
253255 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
254- fn nth ( & mut self , mut n : usize ) -> Option < Self :: Item > {
255- for x in self {
256- if n == 0 { return Some ( x) }
257- n -= 1 ;
258- }
259- None
256+ fn nth ( & mut self , n : usize ) -> Option < Self :: Item > {
257+ self . spec_nth ( n)
260258 }
261259
262260 /// Creates an iterator starting at the same point, but stepping by
@@ -1337,6 +1335,78 @@ pub trait Iterator {
13371335 ( left, right)
13381336 }
13391337
1338+ /// An iterator method that applies a function as long as it returns
1339+ /// successfully, producing a single, final value.
1340+ ///
1341+ /// `try_fold()` takes two arguments: an initial value, and a closure with
1342+ /// two arguments: an 'accumulator', and an element. The closure either
1343+ /// returns successfully, with the value that the accumulator should have
1344+ /// for the next iteration, or it returns failure, with an error value that
1345+ /// is propagated back to the caller immediately (short-circuiting).
1346+ ///
1347+ /// The initial value is the value the accumulator will have on the first
1348+ /// call. If applying the closure succeeded against every element of the
1349+ /// iterator, `try_fold()` returns the final accumulator as success.
1350+ ///
1351+ /// Folding is useful whenever you have a collection of something, and want
1352+ /// to produce a single value from it.
1353+ ///
1354+ /// # Note to Implementors
1355+ ///
1356+ /// Most of the other (forward) methods have default implementations in
1357+ /// terms of this one, so try to implement this explicitly if it can
1358+ /// do something better than the default `for` loop implementation.
1359+ ///
1360+ /// In particular, try to have this call `try_fold()` on the internal parts
1361+ /// from which this iterator is composed. If multiple calls are needed,
1362+ /// the `?` operator be convenient for chaining the accumulator value along,
1363+ /// but beware any invariants that need to be upheld before those early
1364+ /// returns. This is a `&mut self` method, so iteration needs to be
1365+ /// resumable after hitting an error here.
1366+ ///
1367+ /// # Examples
1368+ ///
1369+ /// Basic usage:
1370+ ///
1371+ /// ```
1372+ /// #![feature(iterator_try_fold)]
1373+ /// let a = [1, 2, 3];
1374+ ///
1375+ /// // the checked sum of all of the elements of a
1376+ /// let sum = a.iter()
1377+ /// .try_fold(0i8, |acc, &x| acc.checked_add(x));
1378+ ///
1379+ /// assert_eq!(sum, Some(6));
1380+ /// ```
1381+ ///
1382+ /// Short-circuiting:
1383+ ///
1384+ /// ```
1385+ /// #![feature(iterator_try_fold)]
1386+ /// let a = [10, 20, 30, 100, 40, 50];
1387+ /// let mut it = a.iter();
1388+ ///
1389+ /// // This sum overflows when adding the 100 element
1390+ /// let sum = it.try_fold(0i8, |acc, &x| acc.checked_add(x));
1391+ /// assert_eq!(sum, None);
1392+ ///
1393+ /// // Because it short-circuited, the remaining elements are still
1394+ /// // available through the iterator.
1395+ /// assert_eq!(it.len(), 2);
1396+ /// assert_eq!(it.next(), Some(&40));
1397+ /// ```
1398+ #[ inline]
1399+ #[ unstable( feature = "iterator_try_fold" , issue = "45594" ) ]
1400+ fn try_fold < B , F , R > ( & mut self , init : B , mut f : F ) -> R where
1401+ Self : Sized , F : FnMut ( B , Self :: Item ) -> R , R : Try < Ok =B >
1402+ {
1403+ let mut accum = init;
1404+ while let Some ( x) = self . next ( ) {
1405+ accum = f ( accum, x) ?;
1406+ }
1407+ Try :: from_ok ( accum)
1408+ }
1409+
13401410 /// An iterator method that applies a function, producing a single, final value.
13411411 ///
13421412 /// `fold()` takes two arguments: an initial value, and a closure with two
@@ -1403,14 +1473,10 @@ pub trait Iterator {
14031473 /// ```
14041474 #[ inline]
14051475 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1406- fn fold < B , F > ( self , init : B , mut f : F ) -> B where
1476+ fn fold < B , F > ( mut self , init : B , mut f : F ) -> B where
14071477 Self : Sized , F : FnMut ( B , Self :: Item ) -> B ,
14081478 {
1409- let mut accum = init;
1410- for x in self {
1411- accum = f ( accum, x) ;
1412- }
1413- accum
1479+ self . try_fold ( init, move |acc, x| AlwaysOk ( f ( acc, x) ) ) . 0
14141480 }
14151481
14161482 /// Tests if every element of the iterator matches a predicate.
@@ -1455,12 +1521,10 @@ pub trait Iterator {
14551521 fn all < F > ( & mut self , mut f : F ) -> bool where
14561522 Self : Sized , F : FnMut ( Self :: Item ) -> bool
14571523 {
1458- for x in self {
1459- if !f ( x) {
1460- return false ;
1461- }
1462- }
1463- true
1524+ self . try_fold ( ( ) , move |( ) , x| {
1525+ if f ( x) { LoopState :: Continue ( ( ) ) }
1526+ else { LoopState :: Break ( ( ) ) }
1527+ } ) == LoopState :: Continue ( ( ) )
14641528 }
14651529
14661530 /// Tests if any element of the iterator matches a predicate.
@@ -1506,12 +1570,10 @@ pub trait Iterator {
15061570 Self : Sized ,
15071571 F : FnMut ( Self :: Item ) -> bool
15081572 {
1509- for x in self {
1510- if f ( x) {
1511- return true ;
1512- }
1513- }
1514- false
1573+ self . try_fold ( ( ) , move |( ) , x| {
1574+ if f ( x) { LoopState :: Break ( ( ) ) }
1575+ else { LoopState :: Continue ( ( ) ) }
1576+ } ) == LoopState :: Break ( ( ) )
15151577 }
15161578
15171579 /// Searches for an element of an iterator that satisfies a predicate.
@@ -1562,10 +1624,10 @@ pub trait Iterator {
15621624 Self : Sized ,
15631625 P : FnMut ( & Self :: Item ) -> bool ,
15641626 {
1565- for x in self {
1566- if predicate ( & x) { return Some ( x) }
1567- }
1568- None
1627+ self . try_fold ( ( ) , move | ( ) , x| {
1628+ if predicate ( & x) { LoopState :: Break ( x) }
1629+ else { LoopState :: Continue ( ( ) ) }
1630+ } ) . break_value ( )
15691631 }
15701632
15711633 /// Searches for an element in an iterator, returning its index.
@@ -1623,18 +1685,17 @@ pub trait Iterator {
16231685 ///
16241686 /// ```
16251687 #[ inline]
1688+ #[ rustc_inherit_overflow_checks]
16261689 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
16271690 fn position < P > ( & mut self , mut predicate : P ) -> Option < usize > where
16281691 Self : Sized ,
16291692 P : FnMut ( Self :: Item ) -> bool ,
16301693 {
1631- // `enumerate` might overflow.
1632- for ( i, x) in self . enumerate ( ) {
1633- if predicate ( x) {
1634- return Some ( i) ;
1635- }
1636- }
1637- None
1694+ // The addition might panic on overflow
1695+ self . try_fold ( 0 , move |i, x| {
1696+ if predicate ( x) { LoopState :: Break ( i) }
1697+ else { LoopState :: Continue ( i + 1 ) }
1698+ } ) . break_value ( )
16381699 }
16391700
16401701 /// Searches for an element in an iterator from the right, returning its
@@ -1681,17 +1742,14 @@ pub trait Iterator {
16811742 P : FnMut ( Self :: Item ) -> bool ,
16821743 Self : Sized + ExactSizeIterator + DoubleEndedIterator
16831744 {
1684- let mut i = self . len ( ) ;
1685-
1686- while let Some ( v) = self . next_back ( ) {
1687- // No need for an overflow check here, because `ExactSizeIterator`
1688- // implies that the number of elements fits into a `usize`.
1689- i -= 1 ;
1690- if predicate ( v) {
1691- return Some ( i) ;
1692- }
1693- }
1694- None
1745+ // No need for an overflow check here, because `ExactSizeIterator`
1746+ // implies that the number of elements fits into a `usize`.
1747+ let n = self . len ( ) ;
1748+ self . try_rfold ( n, move |i, x| {
1749+ let i = i - 1 ;
1750+ if predicate ( x) { LoopState :: Break ( i) }
1751+ else { LoopState :: Continue ( i) }
1752+ } ) . break_value ( )
16951753 }
16961754
16971755 /// Returns the maximum element of an iterator.
@@ -1922,10 +1980,10 @@ pub trait Iterator {
19221980 let mut ts: FromA = Default :: default ( ) ;
19231981 let mut us: FromB = Default :: default ( ) ;
19241982
1925- for ( t, u) in self {
1983+ self . for_each ( | ( t, u) | {
19261984 ts. extend ( Some ( t) ) ;
19271985 us. extend ( Some ( u) ) ;
1928- }
1986+ } ) ;
19291987
19301988 ( ts, us)
19311989 }
@@ -2300,17 +2358,17 @@ fn select_fold1<I, B, FProj, FCmp>(mut it: I,
23002358 // start with the first element as our selection. This avoids
23012359 // having to use `Option`s inside the loop, translating to a
23022360 // sizeable performance gain (6x in one case).
2303- it. next ( ) . map ( |mut sel | {
2304- let mut sel_p = f_proj ( & sel ) ;
2361+ it. next ( ) . map ( |first | {
2362+ let first_p = f_proj ( & first ) ;
23052363
2306- for x in it {
2364+ it . fold ( ( first_p , first ) , | ( sel_p , sel ) , x| {
23072365 let x_p = f_proj ( & x) ;
23082366 if f_cmp ( & sel_p, & sel, & x_p, & x) {
2309- sel = x;
2310- sel_p = x_p;
2367+ ( x_p, x)
2368+ } else {
2369+ ( sel_p, sel)
23112370 }
2312- }
2313- ( sel_p, sel)
2371+ } )
23142372 } )
23152373}
23162374
@@ -2323,3 +2381,27 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
23232381 ( * * self ) . nth ( n)
23242382 }
23252383}
2384+
2385+
2386+ trait SpecIterator : Iterator {
2387+ fn spec_nth ( & mut self , n : usize ) -> Option < Self :: Item > ;
2388+ }
2389+
2390+ impl < I : Iterator + ?Sized > SpecIterator for I {
2391+ default fn spec_nth ( & mut self , mut n : usize ) -> Option < Self :: Item > {
2392+ for x in self {
2393+ if n == 0 { return Some ( x) }
2394+ n -= 1 ;
2395+ }
2396+ None
2397+ }
2398+ }
2399+
2400+ impl < I : Iterator + Sized > SpecIterator for I {
2401+ fn spec_nth ( & mut self , n : usize ) -> Option < Self :: Item > {
2402+ self . try_fold ( n, move |i, x| {
2403+ if i == 0 { LoopState :: Break ( x) }
2404+ else { LoopState :: Continue ( i - 1 ) }
2405+ } ) . break_value ( )
2406+ }
2407+ }
0 commit comments