1
- use crate :: cmp:: Ordering ;
1
+ use crate :: cmp:: { self , Ordering } ;
2
2
use crate :: ops:: { Add , Try } ;
3
3
4
4
use super :: super :: LoopState ;
@@ -2223,13 +2223,12 @@ pub trait Iterator {
2223
2223
move |x| ( f ( & x) , x)
2224
2224
}
2225
2225
2226
- // switch to y even if it is only equal, to preserve stability.
2227
2226
#[ 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)
2230
2229
}
2231
2230
2232
- let ( _, x) = select_fold1 ( self . map ( key ( f) ) , select ) ?;
2231
+ let ( _, x) = self . map ( key ( f) ) . max_by ( compare ) ?;
2233
2232
Some ( x)
2234
2233
}
2235
2234
@@ -2252,13 +2251,12 @@ pub trait Iterator {
2252
2251
fn max_by < F > ( self , compare : F ) -> Option < Self :: Item >
2253
2252
where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
2254
2253
{
2255
- // switch to y even if it is only equal, to preserve stability.
2256
2254
#[ 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 )
2259
2257
}
2260
2258
2261
- select_fold1 ( self , select ( compare) )
2259
+ fold1 ( self , fold ( compare) )
2262
2260
}
2263
2261
2264
2262
/// Returns the element that gives the minimum value from the
@@ -2285,13 +2283,12 @@ pub trait Iterator {
2285
2283
move |x| ( f ( & x) , x)
2286
2284
}
2287
2285
2288
- // only switch to y if it is strictly smaller, to preserve stability.
2289
2286
#[ 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)
2292
2289
}
2293
2290
2294
- let ( _, x) = select_fold1 ( self . map ( key ( f) ) , select ) ?;
2291
+ let ( _, x) = self . map ( key ( f) ) . min_by ( compare ) ?;
2295
2292
Some ( x)
2296
2293
}
2297
2294
@@ -2314,13 +2311,12 @@ pub trait Iterator {
2314
2311
fn min_by < F > ( self , compare : F ) -> Option < Self :: Item >
2315
2312
where Self : Sized , F : FnMut ( & Self :: Item , & Self :: Item ) -> Ordering ,
2316
2313
{
2317
- // only switch to y if it is strictly smaller, to preserve stability.
2318
2314
#[ 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 )
2321
2317
}
2322
2318
2323
- select_fold1 ( self , select ( compare) )
2319
+ fold1 ( self , fold ( compare) )
2324
2320
}
2325
2321
2326
2322
@@ -2958,28 +2954,18 @@ pub trait Iterator {
2958
2954
}
2959
2955
}
2960
2956
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.
2967
2958
#[ 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 >
2969
2960
where
2970
2961
I : Iterator ,
2971
- F : FnMut ( & I :: Item , & I :: Item ) -> bool ,
2962
+ F : FnMut ( I :: Item , I :: Item ) -> I :: Item ,
2972
2963
{
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
-
2978
2964
// start with the first element as our selection. This avoids
2979
2965
// having to use `Option`s inside the loop, translating to a
2980
2966
// sizeable performance gain (6x in one case).
2981
2967
let first = it. next ( ) ?;
2982
- Some ( it. fold ( first, select ( f ) ) )
2968
+ Some ( it. fold ( first, f ) )
2983
2969
}
2984
2970
2985
2971
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
0 commit comments