@@ -2008,12 +2008,8 @@ pub trait Iterator {
20082008 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
20092009 fn max ( self ) -> Option < Self :: Item > where Self : Sized , Self :: Item : Ord
20102010 {
2011- select_fold1 ( self ,
2012- |_| ( ) ,
2013- // switch to y even if it is only equal, to preserve
2014- // stability.
2015- |_, x, _, y| * x <= * y)
2016- . map ( |( _, x) | x)
2011+ // switch to y even if it is only equal, to preserve stability.
2012+ select_fold1 ( self , |x, y| x <= y)
20172013 }
20182014
20192015 /// Returns the minimum element of an iterator.
@@ -2038,12 +2034,8 @@ pub trait Iterator {
20382034 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
20392035 fn min ( self ) -> Option < Self :: Item > where Self : Sized , Self :: Item : Ord
20402036 {
2041- select_fold1 ( self ,
2042- |_| ( ) ,
2043- // only switch to y if it is strictly smaller, to
2044- // preserve stability.
2045- |_, x, _, y| * x > * y)
2046- . map ( |( _, x) | x)
2037+ // only switch to y if it is strictly smaller, to preserve stability.
2038+ select_fold1 ( self , |x, y| x > y)
20472039 }
20482040
20492041 /// Returns the element that gives the maximum value from the
@@ -2062,15 +2054,11 @@ pub trait Iterator {
20622054 /// ```
20632055 #[ inline]
20642056 #[ stable( feature = "iter_cmp_by_key" , since = "1.6.0" ) ]
2065- fn max_by_key < B : Ord , F > ( self , f : F ) -> Option < Self :: Item >
2057+ fn max_by_key < B : Ord , F > ( self , mut f : F ) -> Option < Self :: Item >
20662058 where Self : Sized , F : FnMut ( & Self :: Item ) -> B ,
20672059 {
2068- select_fold1 ( self ,
2069- f,
2070- // switch to y even if it is only equal, to preserve
2071- // stability.
2072- |x_p, _, y_p, _| x_p <= y_p)
2073- . map ( |( _, x) | x)
2060+ // switch to y even if it is only equal, to preserve stability.
2061+ select_fold1 ( self . map ( |x| ( f ( & x) , x) ) , |( x_p, _) , ( y_p, _) | x_p <= y_p) . map ( |( _, x) | x)
20742062 }
20752063
20762064 /// Returns the element that gives the maximum value with respect to the
@@ -2092,12 +2080,8 @@ pub trait Iterator {
20922080 fn max_by < F > ( self , mut compare : F ) -> Option < Self :: Item >
20932081 where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
20942082 {
2095- select_fold1 ( self ,
2096- |_| ( ) ,
2097- // switch to y even if it is only equal, to preserve
2098- // stability.
2099- |_, x, _, y| Ordering :: Greater != compare ( x, y) )
2100- . map ( |( _, x) | x)
2083+ // switch to y even if it is only equal, to preserve stability.
2084+ select_fold1 ( self , |x, y| compare ( x, y) != Ordering :: Greater )
21012085 }
21022086
21032087 /// Returns the element that gives the minimum value from the
@@ -2115,15 +2099,11 @@ pub trait Iterator {
21152099 /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
21162100 /// ```
21172101 #[ stable( feature = "iter_cmp_by_key" , since = "1.6.0" ) ]
2118- fn min_by_key < B : Ord , F > ( self , f : F ) -> Option < Self :: Item >
2102+ fn min_by_key < B : Ord , F > ( self , mut f : F ) -> Option < Self :: Item >
21192103 where Self : Sized , F : FnMut ( & Self :: Item ) -> B ,
21202104 {
2121- select_fold1 ( self ,
2122- f,
2123- // only switch to y if it is strictly smaller, to
2124- // preserve stability.
2125- |x_p, _, y_p, _| x_p > y_p)
2126- . map ( |( _, x) | x)
2105+ // only switch to y if it is strictly smaller, to preserve stability.
2106+ select_fold1 ( self . map ( |x| ( f ( & x) , x) ) , |( x_p, _) , ( y_p, _) | x_p > y_p) . map ( |( _, x) | x)
21272107 }
21282108
21292109 /// Returns the element that gives the minimum value with respect to the
@@ -2145,12 +2125,8 @@ pub trait Iterator {
21452125 fn min_by < F > ( self , mut compare : F ) -> Option < Self :: Item >
21462126 where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
21472127 {
2148- select_fold1 ( self ,
2149- |_| ( ) ,
2150- // switch to y even if it is strictly smaller, to
2151- // preserve stability.
2152- |_, x, _, y| Ordering :: Greater == compare ( x, y) )
2153- . map ( |( _, x) | x)
2128+ // switch to y even if it is strictly smaller, to preserve stability.
2129+ select_fold1 ( self , |x, y| compare ( x, y) == Ordering :: Greater )
21542130 }
21552131
21562132
@@ -2693,34 +2669,23 @@ pub trait Iterator {
26932669 }
26942670}
26952671
2696- /// Select an element from an iterator based on the given "projection "
2697- /// and "comparison" function.
2672+ /// Select an element from an iterator based on the given "comparison "
2673+ /// function.
26982674///
26992675/// This is an idiosyncratic helper to try to factor out the
27002676/// commonalities of {max,min}{,_by}. In particular, this avoids
27012677/// having to implement optimizations several times.
27022678#[ inline]
2703- fn select_fold1 < I , B , FProj , FCmp > ( mut it : I ,
2704- mut f_proj : FProj ,
2705- mut f_cmp : FCmp ) -> Option < ( B , I :: Item ) >
2706- where I : Iterator ,
2707- FProj : FnMut ( & I :: Item ) -> B ,
2708- FCmp : FnMut ( & B , & I :: Item , & B , & I :: Item ) -> bool
2679+ fn select_fold1 < I , F > ( mut it : I , mut f : F ) -> Option < I :: Item >
2680+ where
2681+ I : Iterator ,
2682+ F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
27092683{
27102684 // start with the first element as our selection. This avoids
27112685 // having to use `Option`s inside the loop, translating to a
27122686 // sizeable performance gain (6x in one case).
27132687 it. next ( ) . map ( |first| {
2714- let first_p = f_proj ( & first) ;
2715-
2716- it. fold ( ( first_p, first) , |( sel_p, sel) , x| {
2717- let x_p = f_proj ( & x) ;
2718- if f_cmp ( & sel_p, & sel, & x_p, & x) {
2719- ( x_p, x)
2720- } else {
2721- ( sel_p, sel)
2722- }
2723- } )
2688+ it. fold ( first, |sel, x| if f ( & sel, & x) { x } else { sel } )
27242689 } )
27252690}
27262691
0 commit comments