@@ -2448,13 +2448,12 @@ pub trait Iterator {
24482448 /// ```
24492449 #[ inline]
24502450 #[ stable( feature = "iterator_fold_self" , since = "1.51.0" ) ]
2451- fn reduce < F > ( mut self , f : F ) -> Option < Self :: Item >
2451+ fn reduce < F > ( self , f : F ) -> Option < Self :: Item >
24522452 where
24532453 Self : Sized ,
24542454 F : FnMut ( Self :: Item , Self :: Item ) -> Self :: Item ,
24552455 {
2456- let first = self . next ( ) ?;
2457- Some ( self . fold ( first, f) )
2456+ self . fold_first ( core:: convert:: identity, f)
24582457 }
24592458
24602459 /// Reduces the elements to a single one by repeatedly applying a reducing operation. If the
@@ -2537,6 +2536,53 @@ pub trait Iterator {
25372536 }
25382537 }
25392538
2539+ /// Folds every element into an accumulator by applying an operation,
2540+ /// returning the final result. The initial value is derived from the
2541+ /// first element using the provided method.
2542+ ///
2543+ /// If the iterator is empty, returns [`None`]; otherwise, returns the
2544+ /// result of the fold.
2545+ ///
2546+ /// The folding function is a closure with two arguments: an 'accumulator', and an element.
2547+ /// For iterators with at least one element, this is the same as [`reduce()`]
2548+ /// with the first element being fed into the init function
2549+ ///
2550+ /// [`reduce()`]: Iterator::reduce
2551+ ///
2552+ /// # Example
2553+ ///
2554+ /// ```
2555+ /// #![feature(iterator_fold_first)]
2556+ ///
2557+ /// let min_max: (i32, i32) = [3, 1, 4, 1, 5, 9, 2]
2558+ /// .into_iter()
2559+ /// .fold_first(
2560+ /// |first| (first, first),
2561+ /// |(min, max), next| (i32::min(min, next), i32::max(max, next)),
2562+ /// ).unwrap();
2563+ /// assert_eq!(min_max, (1, 9));
2564+ ///
2565+ /// // Which is equivalent to doing it with `fold`:
2566+ /// let folded: (i32, i32) = [3, 1, 4, 1, 5, 9, 2]
2567+ /// .into_iter()
2568+ /// .fold(
2569+ /// (i32::MAX, i32::MIN),
2570+ /// |(min, max), next| (i32::min(min, next), i32::max(max, next)),
2571+ /// );
2572+ /// assert_eq!(min_max, folded);
2573+ /// ```
2574+ #[ inline]
2575+ #[ unstable( feature = "iterator_fold_first" , reason = "new API" , issue = "none" ) ]
2576+ fn fold_first < B , F1 , FR > ( mut self , init : F1 , folding : FR ) -> Option < B >
2577+ where
2578+ Self : Sized ,
2579+ F1 : FnOnce ( Self :: Item ) -> B ,
2580+ FR : FnMut ( B , Self :: Item ) -> B ,
2581+ {
2582+ let first = init ( self . next ( ) ?) ;
2583+ Some ( self . fold ( first, folding) )
2584+ }
2585+
25402586 /// Tests if every element of the iterator matches a predicate.
25412587 ///
25422588 /// `all()` takes a closure that returns `true` or `false`. It applies
0 commit comments