@@ -973,6 +973,24 @@ pub trait Ord: Eq + PartialOrd<Self> {
973973 /// assert_eq!(1.max(2), 2);
974974 /// assert_eq!(2.max(2), 2);
975975 /// ```
976+ /// ```
977+ /// use std::cmp::Ordering;
978+ ///
979+ /// #[derive(Eq)]
980+ /// struct Equal(&'static str);
981+ ///
982+ /// impl PartialEq for Equal {
983+ /// fn eq(&self, other: &Self) -> bool { true }
984+ /// }
985+ /// impl PartialOrd for Equal {
986+ /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
987+ /// }
988+ /// impl Ord for Equal {
989+ /// fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
990+ /// }
991+ ///
992+ /// assert_eq!(Equal("self").max(Equal("other")).0, "other");
993+ /// ```
976994 #[ stable( feature = "ord_max_min" , since = "1.21.0" ) ]
977995 #[ inline]
978996 #[ must_use]
@@ -981,7 +999,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
981999 where
9821000 Self : Sized ,
9831001 {
984- max_by ( self , other, Ord :: cmp )
1002+ if other < self { self } else { other }
9851003 }
9861004
9871005 /// Compares and returns the minimum of two values.
@@ -994,6 +1012,24 @@ pub trait Ord: Eq + PartialOrd<Self> {
9941012 /// assert_eq!(1.min(2), 1);
9951013 /// assert_eq!(2.min(2), 2);
9961014 /// ```
1015+ /// ```
1016+ /// use std::cmp::Ordering;
1017+ ///
1018+ /// #[derive(Eq)]
1019+ /// struct Equal(&'static str);
1020+ ///
1021+ /// impl PartialEq for Equal {
1022+ /// fn eq(&self, other: &Self) -> bool { true }
1023+ /// }
1024+ /// impl PartialOrd for Equal {
1025+ /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
1026+ /// }
1027+ /// impl Ord for Equal {
1028+ /// fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
1029+ /// }
1030+ ///
1031+ /// assert_eq!(Equal("self").min(Equal("other")).0, "self");
1032+ /// ```
9971033 #[ stable( feature = "ord_max_min" , since = "1.21.0" ) ]
9981034 #[ inline]
9991035 #[ must_use]
@@ -1002,7 +1038,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
10021038 where
10031039 Self : Sized ,
10041040 {
1005- min_by ( self , other, Ord :: cmp )
1041+ if other < self { other } else { self }
10061042 }
10071043
10081044 /// Restrict a value to a certain interval.
@@ -1414,6 +1450,24 @@ pub macro PartialOrd($item:item) {
14141450/// assert_eq!(cmp::min(1, 2), 1);
14151451/// assert_eq!(cmp::min(2, 2), 2);
14161452/// ```
1453+ /// ```
1454+ /// use std::cmp::{self, Ordering};
1455+ ///
1456+ /// #[derive(Eq)]
1457+ /// struct Equal(&'static str);
1458+ ///
1459+ /// impl PartialEq for Equal {
1460+ /// fn eq(&self, other: &Self) -> bool { true }
1461+ /// }
1462+ /// impl PartialOrd for Equal {
1463+ /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
1464+ /// }
1465+ /// impl Ord for Equal {
1466+ /// fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
1467+ /// }
1468+ ///
1469+ /// assert_eq!(cmp::min(Equal("v1"), Equal("v2")).0, "v1");
1470+ /// ```
14171471#[ inline]
14181472#[ must_use]
14191473#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1431,20 +1485,22 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
14311485/// ```
14321486/// use std::cmp;
14331487///
1434- /// let result = cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
1435- /// assert_eq!(result, 1);
1488+ /// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
14361489///
1437- /// let result = cmp::min_by(-2, 3, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
1438- /// assert_eq!(result, -2);
1490+ /// let result = cmp::min_by(2, -1, abs_cmp);
1491+ /// assert_eq!(result, -1);
1492+ ///
1493+ /// let result = cmp::min_by(2, -3, abs_cmp);
1494+ /// assert_eq!(result, 2);
1495+ ///
1496+ /// let result = cmp::min_by(1, -1, abs_cmp);
1497+ /// assert_eq!(result, 1);
14391498/// ```
14401499#[ inline]
14411500#[ must_use]
14421501#[ stable( feature = "cmp_min_max_by" , since = "1.53.0" ) ]
14431502pub fn min_by < T , F : FnOnce ( & T , & T ) -> Ordering > ( v1 : T , v2 : T , compare : F ) -> T {
1444- match compare ( & v1, & v2) {
1445- Ordering :: Less | Ordering :: Equal => v1,
1446- Ordering :: Greater => v2,
1447- }
1503+ if compare ( & v2, & v1) . is_lt ( ) { v2 } else { v1 }
14481504}
14491505
14501506/// Returns the element that gives the minimum value from the specified function.
@@ -1456,17 +1512,20 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
14561512/// ```
14571513/// use std::cmp;
14581514///
1459- /// let result = cmp::min_by_key(- 2, 1, |x: &i32| x.abs());
1460- /// assert_eq!(result, 1);
1515+ /// let result = cmp::min_by_key(2, - 1, |x: &i32| x.abs());
1516+ /// assert_eq!(result, - 1);
14611517///
1462- /// let result = cmp::min_by_key(-2, 2, |x: &i32| x.abs());
1463- /// assert_eq!(result, -2);
1518+ /// let result = cmp::min_by_key(2, -3, |x: &i32| x.abs());
1519+ /// assert_eq!(result, 2);
1520+ ///
1521+ /// let result = cmp::min_by_key(1, -1, |x: &i32| x.abs());
1522+ /// assert_eq!(result, 1);
14641523/// ```
14651524#[ inline]
14661525#[ must_use]
14671526#[ stable( feature = "cmp_min_max_by" , since = "1.53.0" ) ]
14681527pub fn min_by_key < T , F : FnMut ( & T ) -> K , K : Ord > ( v1 : T , v2 : T , mut f : F ) -> T {
1469- min_by ( v1 , v2 , |v1 , v2| f ( v1) . cmp ( & f ( v2 ) ) )
1528+ if f ( & v2 ) < f ( & v1) { v2 } else { v1 }
14701529}
14711530
14721531/// Compares and returns the maximum of two values.
@@ -1483,6 +1542,24 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
14831542/// assert_eq!(cmp::max(1, 2), 2);
14841543/// assert_eq!(cmp::max(2, 2), 2);
14851544/// ```
1545+ /// ```
1546+ /// use std::cmp::{self, Ordering};
1547+ ///
1548+ /// #[derive(Eq)]
1549+ /// struct Equal(&'static str);
1550+ ///
1551+ /// impl PartialEq for Equal {
1552+ /// fn eq(&self, other: &Self) -> bool { true }
1553+ /// }
1554+ /// impl PartialOrd for Equal {
1555+ /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
1556+ /// }
1557+ /// impl Ord for Equal {
1558+ /// fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
1559+ /// }
1560+ ///
1561+ /// assert_eq!(cmp::max(Equal("v1"), Equal("v2")).0, "v2");
1562+ /// ```
14861563#[ inline]
14871564#[ must_use]
14881565#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -1500,20 +1577,22 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
15001577/// ```
15011578/// use std::cmp;
15021579///
1503- /// let result = cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
1580+ /// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
1581+ ///
1582+ /// let result = cmp::max_by(3, -2, abs_cmp) ;
1583+ /// assert_eq!(result, 3);
1584+ ///
1585+ /// let result = cmp::max_by(1, -2, abs_cmp);
15041586/// assert_eq!(result, -2);
15051587///
1506- /// let result = cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())) ;
1507- /// assert_eq!(result, 2 );
1588+ /// let result = cmp::max_by(1, -1, abs_cmp) ;
1589+ /// assert_eq!(result, -1 );
15081590/// ```
15091591#[ inline]
15101592#[ must_use]
15111593#[ stable( feature = "cmp_min_max_by" , since = "1.53.0" ) ]
15121594pub fn max_by < T , F : FnOnce ( & T , & T ) -> Ordering > ( v1 : T , v2 : T , compare : F ) -> T {
1513- match compare ( & v1, & v2) {
1514- Ordering :: Less | Ordering :: Equal => v2,
1515- Ordering :: Greater => v1,
1516- }
1595+ if compare ( & v2, & v1) . is_lt ( ) { v1 } else { v2 }
15171596}
15181597
15191598/// Returns the element that gives the maximum value from the specified function.
@@ -1525,17 +1604,20 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
15251604/// ```
15261605/// use std::cmp;
15271606///
1528- /// let result = cmp::max_by_key(-2, 1, |x: &i32| x.abs());
1607+ /// let result = cmp::max_by_key(3, -2, |x: &i32| x.abs());
1608+ /// assert_eq!(result, 3);
1609+ ///
1610+ /// let result = cmp::max_by_key(1, -2, |x: &i32| x.abs());
15291611/// assert_eq!(result, -2);
15301612///
1531- /// let result = cmp::max_by_key(-2, 2 , |x: &i32| x.abs());
1532- /// assert_eq!(result, 2 );
1613+ /// let result = cmp::max_by_key(1, -1 , |x: &i32| x.abs());
1614+ /// assert_eq!(result, -1 );
15331615/// ```
15341616#[ inline]
15351617#[ must_use]
15361618#[ stable( feature = "cmp_min_max_by" , since = "1.53.0" ) ]
15371619pub fn max_by_key < T , F : FnMut ( & T ) -> K , K : Ord > ( v1 : T , v2 : T , mut f : F ) -> T {
1538- max_by ( v1 , v2 , |v1 , v2| f ( v1) . cmp ( & f ( v2 ) ) )
1620+ if f ( & v2 ) < f ( & v1) { v1 } else { v2 }
15391621}
15401622
15411623/// Compares and sorts two values, returning minimum and maximum.
@@ -1549,21 +1631,40 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
15491631/// use std::cmp;
15501632///
15511633/// assert_eq!(cmp::minmax(1, 2), [1, 2]);
1552- /// assert_eq!(cmp::minmax(2, 2 ), [2 , 2]);
1634+ /// assert_eq!(cmp::minmax(2, 1 ), [1 , 2]);
15531635///
15541636/// // You can destructure the result using array patterns
15551637/// let [min, max] = cmp::minmax(42, 17);
15561638/// assert_eq!(min, 17);
15571639/// assert_eq!(max, 42);
15581640/// ```
1641+ /// ```
1642+ /// #![feature(cmp_minmax)]
1643+ /// use std::cmp::{self, Ordering};
1644+ ///
1645+ /// #[derive(Eq)]
1646+ /// struct Equal(&'static str);
1647+ ///
1648+ /// impl PartialEq for Equal {
1649+ /// fn eq(&self, other: &Self) -> bool { true }
1650+ /// }
1651+ /// impl PartialOrd for Equal {
1652+ /// fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(Ordering::Equal) }
1653+ /// }
1654+ /// impl Ord for Equal {
1655+ /// fn cmp(&self, other: &Self) -> Ordering { Ordering::Equal }
1656+ /// }
1657+ ///
1658+ /// assert_eq!(cmp::minmax(Equal("v1"), Equal("v2")).map(|v| v.0), ["v1", "v2"]);
1659+ /// ```
15591660#[ inline]
15601661#[ must_use]
15611662#[ unstable( feature = "cmp_minmax" , issue = "115939" ) ]
15621663pub fn minmax < T > ( v1 : T , v2 : T ) -> [ T ; 2 ]
15631664where
15641665 T : Ord ,
15651666{
1566- if v1 <= v2 { [ v1 , v2 ] } else { [ v2 , v1 ] }
1667+ if v2 < v1 { [ v2 , v1 ] } else { [ v1 , v2 ] }
15671668}
15681669
15691670/// Returns minimum and maximum values with respect to the specified comparison function.
@@ -1576,11 +1677,14 @@ where
15761677/// #![feature(cmp_minmax)]
15771678/// use std::cmp;
15781679///
1579- /// assert_eq!(cmp::minmax_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [1, -2]);
1580- /// assert_eq!(cmp::minmax_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [-2, 2]);
1680+ /// let abs_cmp = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
1681+ ///
1682+ /// assert_eq!(cmp::minmax_by(-2, 1, abs_cmp), [1, -2]);
1683+ /// assert_eq!(cmp::minmax_by(-1, 2, abs_cmp), [-1, 2]);
1684+ /// assert_eq!(cmp::minmax_by(-2, 2, abs_cmp), [-2, 2]);
15811685///
15821686/// // You can destructure the result using array patterns
1583- /// let [min, max] = cmp::minmax_by(-42, 17, |x: &i32, y: &i32| x.abs().cmp(&y.abs()) );
1687+ /// let [min, max] = cmp::minmax_by(-42, 17, abs_cmp );
15841688/// assert_eq!(min, 17);
15851689/// assert_eq!(max, -42);
15861690/// ```
@@ -1591,7 +1695,7 @@ pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
15911695where
15921696 F : FnOnce ( & T , & T ) -> Ordering ,
15931697{
1594- if compare ( & v1 , & v2 ) . is_le ( ) { [ v1 , v2 ] } else { [ v2 , v1 ] }
1698+ if compare ( & v2 , & v1 ) . is_lt ( ) { [ v2 , v1 ] } else { [ v1 , v2 ] }
15951699}
15961700
15971701/// Returns minimum and maximum values with respect to the specified key function.
@@ -1620,7 +1724,7 @@ where
16201724 F : FnMut ( & T ) -> K ,
16211725 K : Ord ,
16221726{
1623- minmax_by ( v1 , v2, |v1 , v2| f ( v1 ) . cmp ( & f ( v2 ) ) )
1727+ if f ( & v2 ) < f ( & v1 ) { [ v2, v1 ] } else { [ v1 , v2 ] }
16241728}
16251729
16261730// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
0 commit comments