@@ -2008,12 +2008,7 @@ 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+ self . max_by ( Ord :: cmp)
20172012 }
20182013
20192014 /// Returns the minimum element of an iterator.
@@ -2038,12 +2033,7 @@ pub trait Iterator {
20382033 #[ stable( feature = "rust1" , since = "1.0.0" ) ]
20392034 fn min ( self ) -> Option < Self :: Item > where Self : Sized , Self :: Item : Ord
20402035 {
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)
2036+ self . min_by ( Ord :: cmp)
20472037 }
20482038
20492039 /// Returns the element that gives the maximum value from the
@@ -2062,15 +2052,11 @@ pub trait Iterator {
20622052 /// ```
20632053 #[ inline]
20642054 #[ stable( feature = "iter_cmp_by_key" , since = "1.6.0" ) ]
2065- fn max_by_key < B : Ord , F > ( self , f : F ) -> Option < Self :: Item >
2055+ fn max_by_key < B : Ord , F > ( self , mut f : F ) -> Option < Self :: Item >
20662056 where Self : Sized , F : FnMut ( & Self :: Item ) -> B ,
20672057 {
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)
2058+ // switch to y even if it is only equal, to preserve stability.
2059+ select_fold1 ( self . map ( |x| ( f ( & x) , x) ) , |( x_p, _) , ( y_p, _) | x_p <= y_p) . map ( |( _, x) | x)
20742060 }
20752061
20762062 /// Returns the element that gives the maximum value with respect to the
@@ -2092,12 +2078,8 @@ pub trait Iterator {
20922078 fn max_by < F > ( self , mut compare : F ) -> Option < Self :: Item >
20932079 where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
20942080 {
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)
2081+ // switch to y even if it is only equal, to preserve stability.
2082+ select_fold1 ( self , |x, y| compare ( x, y) != Ordering :: Greater )
21012083 }
21022084
21032085 /// Returns the element that gives the minimum value from the
@@ -2115,15 +2097,11 @@ pub trait Iterator {
21152097 /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
21162098 /// ```
21172099 #[ stable( feature = "iter_cmp_by_key" , since = "1.6.0" ) ]
2118- fn min_by_key < B : Ord , F > ( self , f : F ) -> Option < Self :: Item >
2100+ fn min_by_key < B : Ord , F > ( self , mut f : F ) -> Option < Self :: Item >
21192101 where Self : Sized , F : FnMut ( & Self :: Item ) -> B ,
21202102 {
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)
2103+ // only switch to y if it is strictly smaller, to preserve stability.
2104+ select_fold1 ( self . map ( |x| ( f ( & x) , x) ) , |( x_p, _) , ( y_p, _) | x_p > y_p) . map ( |( _, x) | x)
21272105 }
21282106
21292107 /// Returns the element that gives the minimum value with respect to the
@@ -2145,12 +2123,8 @@ pub trait Iterator {
21452123 fn min_by < F > ( self , mut compare : F ) -> Option < Self :: Item >
21462124 where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
21472125 {
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)
2126+ // only switch to y if it is strictly smaller, to preserve stability.
2127+ select_fold1 ( self , |x, y| compare ( x, y) == Ordering :: Greater )
21542128 }
21552129
21562130
@@ -2693,34 +2667,23 @@ pub trait Iterator {
26932667 }
26942668}
26952669
2696- /// Select an element from an iterator based on the given "projection "
2697- /// and "comparison" function.
2670+ /// Select an element from an iterator based on the given "comparison "
2671+ /// function.
26982672///
26992673/// This is an idiosyncratic helper to try to factor out the
27002674/// commonalities of {max,min}{,_by}. In particular, this avoids
27012675/// having to implement optimizations several times.
27022676#[ 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
2677+ fn select_fold1 < I , F > ( mut it : I , mut f : F ) -> Option < I :: Item >
2678+ where
2679+ I : Iterator ,
2680+ F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
27092681{
27102682 // start with the first element as our selection. This avoids
27112683 // having to use `Option`s inside the loop, translating to a
27122684 // sizeable performance gain (6x in one case).
27132685 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- } )
2686+ it. fold ( first, |sel, x| if f ( & sel, & x) { x } else { sel } )
27242687 } )
27252688}
27262689
0 commit comments