1- use crate :: cmp:: Ordering ;
1+ use crate :: cmp:: { self , Ordering } ;
22use crate :: ops:: { Add , Try } ;
33
44use super :: super :: LoopState ;
@@ -2223,13 +2223,12 @@ pub trait Iterator {
22232223 move |x| ( f ( & x) , x)
22242224 }
22252225
2226- // switch to y even if it is only equal, to preserve stability.
22272226 #[ inline]
2228- fn select < T , B : Ord > ( ( x_p, _) : & ( B , T ) , ( y_p, _) : & ( B , T ) ) -> bool {
2229- x_p <= y_p
2227+ fn compare < T , B : Ord > ( ( x_p, _) : & ( B , T ) , ( y_p, _) : & ( B , T ) ) -> Ordering {
2228+ x_p. cmp ( y_p)
22302229 }
22312230
2232- let ( _, x) = select_fold1 ( self . map ( key ( f) ) , select ) ?;
2231+ let ( _, x) = self . map ( key ( f) ) . max_by ( compare ) ?;
22332232 Some ( x)
22342233 }
22352234
@@ -2252,13 +2251,12 @@ pub trait Iterator {
22522251 fn max_by < F > ( self , compare : F ) -> Option < Self :: Item >
22532252 where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
22542253 {
2255- // switch to y even if it is only equal, to preserve stability.
22562254 #[ inline]
2257- fn select < T > ( mut compare : impl FnMut ( & T , & T ) -> Ordering ) -> impl FnMut ( & T , & T ) -> bool {
2258- move |x, y| compare ( x, y) != Ordering :: Greater
2255+ fn fold < T > ( mut compare : impl FnMut ( & T , & T ) -> Ordering ) -> impl FnMut ( T , T ) -> T {
2256+ move |x, y| cmp :: max_by ( x, y, & mut compare )
22592257 }
22602258
2261- select_fold1 ( self , select ( compare) )
2259+ fold1 ( self , fold ( compare) )
22622260 }
22632261
22642262 /// Returns the element that gives the minimum value from the
@@ -2285,13 +2283,12 @@ pub trait Iterator {
22852283 move |x| ( f ( & x) , x)
22862284 }
22872285
2288- // only switch to y if it is strictly smaller, to preserve stability.
22892286 #[ inline]
2290- fn select < T , B : Ord > ( ( x_p, _) : & ( B , T ) , ( y_p, _) : & ( B , T ) ) -> bool {
2291- x_p > y_p
2287+ fn compare < T , B : Ord > ( ( x_p, _) : & ( B , T ) , ( y_p, _) : & ( B , T ) ) -> Ordering {
2288+ x_p. cmp ( y_p)
22922289 }
22932290
2294- let ( _, x) = select_fold1 ( self . map ( key ( f) ) , select ) ?;
2291+ let ( _, x) = self . map ( key ( f) ) . min_by ( compare ) ?;
22952292 Some ( x)
22962293 }
22972294
@@ -2314,13 +2311,12 @@ pub trait Iterator {
23142311 fn min_by < F > ( self , compare : F ) -> Option < Self :: Item >
23152312 where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
23162313 {
2317- // only switch to y if it is strictly smaller, to preserve stability.
23182314 #[ inline]
2319- fn select < T > ( mut compare : impl FnMut ( & T , & T ) -> Ordering ) -> impl FnMut ( & T , & T ) -> bool {
2320- move |x, y| compare ( x, y) == Ordering :: Greater
2315+ fn fold < T > ( mut compare : impl FnMut ( & T , & T ) -> Ordering ) -> impl FnMut ( T , T ) -> T {
2316+ move |x, y| cmp :: min_by ( x, y, & mut compare )
23212317 }
23222318
2323- select_fold1 ( self , select ( compare) )
2319+ fold1 ( self , fold ( compare) )
23242320 }
23252321
23262322
@@ -2958,28 +2954,18 @@ pub trait Iterator {
29582954 }
29592955}
29602956
2961- /// Select an element from an iterator based on the given "comparison"
2962- /// function.
2963- ///
2964- /// This is an idiosyncratic helper to try to factor out the
2965- /// commonalities of {max,min}{,_by}. In particular, this avoids
2966- /// having to implement optimizations several times.
2957+ /// Fold an iterator without having to provide an initial value.
29672958#[ inline]
2968- fn select_fold1 < I , F > ( mut it : I , f : F ) -> Option < I :: Item >
2959+ fn fold1 < I , F > ( mut it : I , f : F ) -> Option < I :: Item >
29692960 where
29702961 I : Iterator ,
2971- F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
2962+ F : FnMut ( I :: Item , I :: Item ) -> I :: Item ,
29722963{
2973- #[ inline]
2974- fn select < T > ( mut f : impl FnMut ( & T , & T ) -> bool ) -> impl FnMut ( T , T ) -> T {
2975- move |sel, x| if f ( & sel, & x) { x } else { sel }
2976- }
2977-
29782964 // start with the first element as our selection. This avoids
29792965 // having to use `Option`s inside the loop, translating to a
29802966 // sizeable performance gain (6x in one case).
29812967 let first = it. next ( ) ?;
2982- Some ( it. fold ( first, select ( f ) ) )
2968+ Some ( it. fold ( first, f ) )
29832969}
29842970
29852971#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments