Skip to content

Commit 44351ed

Browse files
Rollup merge of rust-lang#44097 - Xaeroxe:clamp, r=burntsushi
Add clamp functions Implementation of clamp feature: Tracking issue: rust-lang#44095 RFC: rust-lang/rfcs#1961
2 parents 3681220 + b762283 commit 44351ed

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

src/libcore/cmp.rs

+24
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,30 @@ pub trait Ord: Eq + PartialOrd<Self> {
481481
where Self: Sized {
482482
if self <= other { self } else { other }
483483
}
484+
485+
/// Returns max if self is greater than max, and min if self is less than min.
486+
/// Otherwise this will return self.
487+
///
488+
/// # Examples
489+
///
490+
/// ```
491+
/// #![feature(clamp)]
492+
///
493+
/// assert!((-3).clamp(-2, 1) == -2);
494+
/// assert!(0.clamp(-2, 1) == 0);
495+
/// assert!(2.clamp(-2, 1) == 1);
496+
/// ```
497+
///
498+
/// # Panics
499+
/// Panics if min > max.
500+
#[unstable(feature = "clamp", issue = "44095")]
501+
fn clamp(self, min: Self, max: Self) -> Self
502+
where Self: Sized {
503+
assert!(min <= max);
504+
if self < min { min }
505+
else if self > max { max }
506+
else { self }
507+
}
484508
}
485509

486510
#[stable(feature = "rust1", since = "1.0.0")]

src/libstd/f32.rs

+44
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,32 @@ impl f32 {
10801080
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
10811081
}
10821082

1083+
/// Returns max if self is greater than max, and min if self is less than min.
1084+
/// Otherwise this returns self.
1085+
///
1086+
/// # Examples
1087+
///
1088+
/// ```
1089+
/// #![feature(clamp)]
1090+
/// use std::f32::NAN;
1091+
/// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32);
1092+
/// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32);
1093+
/// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32);
1094+
/// assert!((NAN).clamp(-2.0f32, 1.0f32).is_nan());
1095+
/// ```
1096+
///
1097+
/// # Panics
1098+
/// Panics if min > max, min is NaN, or max is NaN.
1099+
#[unstable(feature = "clamp", issue = "44095")]
1100+
#[inline]
1101+
pub fn clamp(self, min: f32, max: f32) -> f32 {
1102+
assert!(min <= max);
1103+
let mut x = self;
1104+
if x < min { x = min; }
1105+
if x > max { x = max; }
1106+
x
1107+
}
1108+
10831109
/// Raw transmutation to `u32`.
10841110
///
10851111
/// Converts the `f32` into its raw memory representation,
@@ -1751,4 +1777,22 @@ mod tests {
17511777
assert_ne!(nan_masked & QNAN_MASK, 0);
17521778
assert!(nan_masked_fl.is_nan());
17531779
}
1780+
1781+
#[test]
1782+
#[should_panic]
1783+
fn test_clamp_min_greater_than_max() {
1784+
1.0f32.clamp(3.0, 1.0);
1785+
}
1786+
1787+
#[test]
1788+
#[should_panic]
1789+
fn test_clamp_min_is_nan() {
1790+
1.0f32.clamp(NAN, 1.0);
1791+
}
1792+
1793+
#[test]
1794+
#[should_panic]
1795+
fn test_clamp_max_is_nan() {
1796+
1.0f32.clamp(3.0, NAN);
1797+
}
17541798
}

src/libstd/f64.rs

+44
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,32 @@ impl f64 {
970970
0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
971971
}
972972

973+
/// Returns max if self is greater than max, and min if self is less than min.
974+
/// Otherwise this returns self.
975+
///
976+
/// # Examples
977+
///
978+
/// ```
979+
/// #![feature(clamp)]
980+
/// use std::f64::NAN;
981+
/// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64);
982+
/// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64);
983+
/// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64);
984+
/// assert!((NAN).clamp(-2.0f64, 1.0f64).is_nan());
985+
/// ```
986+
///
987+
/// # Panics
988+
/// Panics if min > max, min is NaN, or max is NaN.
989+
#[unstable(feature = "clamp", issue = "44095")]
990+
#[inline]
991+
pub fn clamp(self, min: f64, max: f64) -> f64 {
992+
assert!(min <= max);
993+
let mut x = self;
994+
if x < min { x = min; }
995+
if x > max { x = max; }
996+
x
997+
}
998+
973999
// Solaris/Illumos requires a wrapper around log, log2, and log10 functions
9741000
// because of their non-standard behavior (e.g. log(-n) returns -Inf instead
9751001
// of expected NaN).
@@ -1642,4 +1668,22 @@ mod tests {
16421668
assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
16431669
assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
16441670
}
1671+
1672+
#[test]
1673+
#[should_panic]
1674+
fn test_clamp_min_greater_than_max() {
1675+
1.0f64.clamp(3.0, 1.0);
1676+
}
1677+
1678+
#[test]
1679+
#[should_panic]
1680+
fn test_clamp_min_is_nan() {
1681+
1.0f64.clamp(NAN, 1.0);
1682+
}
1683+
1684+
#[test]
1685+
#[should_panic]
1686+
fn test_clamp_max_is_nan() {
1687+
1.0f64.clamp(3.0, NAN);
1688+
}
16451689
}

src/libstd/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@
249249
#![feature(cfg_target_vendor)]
250250
#![feature(char_error_internals)]
251251
#![feature(char_internals)]
252+
#![feature(clamp)]
252253
#![feature(collections_range)]
253254
#![feature(compiler_builtins_lib)]
254255
#![feature(const_fn)]

0 commit comments

Comments
 (0)