blob: a737b59bbbe51b56feae77191514c5a4b374f146 [file] [edit]
use crate::marker::Destruct;
use crate::ops::{RangeFrom, RangeFull, RangeInclusive, RangeToInclusive};
/// Trait for ranges supported by [`Ord::clamp_to`].
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
pub const trait ClampBounds<T>: Sized {
/// The implementation of [`Ord::clamp_to`].
fn clamp(self, value: T) -> T
where
T: [const] Destruct;
}
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl<T> ClampBounds<T> for RangeFrom<T>
where
T: [const] Ord,
{
fn clamp(self, value: T) -> T
where
T: [const] Destruct,
{
value.max(self.start)
}
}
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl<T> ClampBounds<T> for RangeToInclusive<T>
where
T: [const] Ord,
{
fn clamp(self, value: T) -> T
where
T: [const] Destruct,
{
value.min(self.end)
}
}
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl<T> ClampBounds<T> for RangeInclusive<T>
where
T: [const] Ord,
{
fn clamp(self, value: T) -> T
where
T: [const] Destruct,
{
let (start, end) = self.into_inner();
value.clamp(start, end)
}
}
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl<T> ClampBounds<T> for RangeFull {
fn clamp(self, value: T) -> T {
value
}
}
macro impl_for_float($t:ty) {
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl ClampBounds<$t> for RangeFrom<$t> {
fn clamp(self, value: $t) -> $t {
assert!(!self.start.is_nan(), "start was NaN");
value.max(self.start)
}
}
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl ClampBounds<$t> for RangeToInclusive<$t> {
fn clamp(self, value: $t) -> $t {
assert!(!self.end.is_nan(), "end was NaN");
value.min(self.end)
}
}
#[unstable(feature = "clamp_bounds", issue = "147781")]
#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
const impl ClampBounds<$t> for RangeInclusive<$t> {
#[expect(
clippy::neg_cmp_op_on_partial_ord,
reason = "NaN check is intentionally included in comparison"
)]
fn clamp(self, value: $t) -> $t {
let (start, end) = self.into_inner();
assert!(start <= end, "start > end, or either was NaN");
value.clamp(start, end)
}
}
}
// #[unstable(feature = "f16", issue = "116909")]
impl_for_float!(f16);
impl_for_float!(f32);
impl_for_float!(f64);
// #[unstable(feature = "f128", issue = "116909")]
impl_for_float!(f128);