Skip to content

Commit 5910cce

Browse files
committed
Add minmax* functions to core::cmp
1 parent e91364b commit 5910cce

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

library/core/src/cmp.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,97 @@ where
12961296
max_by(v1, v2, const |v1, v2| f(v1).cmp(&f(v2)))
12971297
}
12981298

1299+
/// Compares and sorts two values, returning minimum and maximum.
1300+
///
1301+
/// Returns `[v1, v2]` if the comparison determines them to be equal.
1302+
///
1303+
/// # Examples
1304+
///
1305+
/// ```
1306+
/// #![feature(cmp_minmax)]
1307+
/// use std::cmp;
1308+
///
1309+
/// assert_eq!(cmp::minmax(1, 2), [1, 2]);
1310+
/// assert_eq!(cmp::minmax(2, 2), [2, 2]);
1311+
///
1312+
/// // You can destructure the result using array patterns
1313+
/// let [min, max] = cmp::minmax(42, 17);
1314+
/// assert_eq!(min, 17);
1315+
/// assert_eq!(max, 42);
1316+
/// ```
1317+
#[inline]
1318+
#[must_use]
1319+
#[unstable(feature = "cmp_minmax", issue = "none")]
1320+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1321+
pub const fn minmax<T>(v1: T, v2: T) -> [T; 2]
1322+
where
1323+
T: ~const Ord,
1324+
{
1325+
// This could have been `v1 <= v2` if not for the `const` shenanigans
1326+
// (namely `~const Ord` doesn't allow using comparison ops)
1327+
if v1.cmp(&v2).is_le() { [v1, v2] } else { [v2, v1] }
1328+
}
1329+
1330+
/// Returns minimum and maximum values with respect to the specified comparison function.
1331+
///
1332+
/// Returns `[v1, v2]` if the comparison determines them to be equal.
1333+
///
1334+
/// # Examples
1335+
///
1336+
/// ```
1337+
/// #![feature(cmp_minmax)]
1338+
/// use std::cmp;
1339+
///
1340+
/// assert_eq!(cmp::minmax_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [1, -2]);
1341+
/// assert_eq!(cmp::minmax_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), [-2, 2]);
1342+
///
1343+
/// // You can destructure the result using array patterns
1344+
/// let [min, max] = cmp::minmax_by(-42, 17, |x: &i32, y: &i32| x.abs().cmp(&y.abs()));
1345+
/// assert_eq!(min, 17);
1346+
/// assert_eq!(max, -42);
1347+
/// ```
1348+
#[inline]
1349+
#[must_use]
1350+
#[unstable(feature = "cmp_minmax", issue = "none")]
1351+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1352+
pub const fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
1353+
where
1354+
F: ~const FnOnce(&T, &T) -> Ordering,
1355+
{
1356+
if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] }
1357+
}
1358+
1359+
/// Returns minimum and maximum values with respect to the specified key function.
1360+
///
1361+
/// Returns `[v1, v2]` if the comparison determines them to be equal.
1362+
///
1363+
/// # Examples
1364+
///
1365+
/// ```
1366+
/// #![feature(cmp_minmax)]
1367+
/// use std::cmp;
1368+
///
1369+
/// assert_eq!(cmp::minmax_by_key(-2, 1, |x: &i32| x.abs()), [1, -2]);
1370+
/// assert_eq!(cmp::minmax_by_key(-2, 2, |x: &i32| x.abs()), [-2, 2]);
1371+
///
1372+
/// // You can destructure the result using array patterns
1373+
/// let [min, max] = cmp::minmax_by_key(-42, 17, |x: &i32| x.abs());
1374+
/// assert_eq!(min, 17);
1375+
/// assert_eq!(max, -42);
1376+
/// ```
1377+
#[inline]
1378+
#[must_use]
1379+
#[unstable(feature = "cmp_minmax", issue = "none")]
1380+
#[rustc_const_unstable(feature = "const_cmp", issue = "92391")]
1381+
pub const fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2]
1382+
where
1383+
F: ~const Destruct,
1384+
F: ~const FnMut(&T) -> K,
1385+
K: ~const Ord,
1386+
{
1387+
minmax_by(v1, v2, const |v1, v2| f(v1).cmp(&f(v2)))
1388+
}
1389+
12991390
// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
13001391
mod impls {
13011392
use crate::cmp::Ordering::{self, Equal, Greater, Less};

0 commit comments

Comments
 (0)