1use crate::marker::Destruct;
2use crate::ops::{RangeFrom, RangeFull, RangeInclusive, RangeToInclusive};
3
4#[unstable(feature = "clamp_bounds", issue = "147781")]
6#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
7pub const trait ClampBounds<T>: Sized {
8 fn clamp(self, value: T) -> T
10 where
11 T: [const] Destruct;
12}
13
14#[unstable(feature = "clamp_bounds", issue = "147781")]
15#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
16const impl<T> ClampBounds<T> for RangeFrom<T>
17where
18 T: [const] Ord,
19{
20 fn clamp(self, value: T) -> T
21 where
22 T: [const] Destruct,
23 {
24 value.max(self.start)
25 }
26}
27
28#[unstable(feature = "clamp_bounds", issue = "147781")]
29#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
30const impl<T> ClampBounds<T> for RangeToInclusive<T>
31where
32 T: [const] Ord,
33{
34 fn clamp(self, value: T) -> T
35 where
36 T: [const] Destruct,
37 {
38 value.min(self.end)
39 }
40}
41
42#[unstable(feature = "clamp_bounds", issue = "147781")]
43#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
44const impl<T> ClampBounds<T> for RangeInclusive<T>
45where
46 T: [const] Ord,
47{
48 fn clamp(self, value: T) -> T
49 where
50 T: [const] Destruct,
51 {
52 let (start, end) = self.into_inner();
53 value.clamp(start, end)
54 }
55}
56
57#[unstable(feature = "clamp_bounds", issue = "147781")]
58#[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
59const impl<T> ClampBounds<T> for RangeFull {
60 fn clamp(self, value: T) -> T {
61 value
62 }
63}
64
65macro impl_for_float($t:ty) {
66 #[unstable(feature = "clamp_bounds", issue = "147781")]
67 #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
68 const impl ClampBounds<$t> for RangeFrom<$t> {
69 #[inline]
70 fn clamp(self, value: $t) -> $t {
71 assert!(!self.start.is_nan(), "start was NaN");
72 value.max(self.start)
73 }
74 }
75
76 #[unstable(feature = "clamp_bounds", issue = "147781")]
77 #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
78 const impl ClampBounds<$t> for RangeToInclusive<$t> {
79 #[inline]
80 fn clamp(self, value: $t) -> $t {
81 assert!(!self.end.is_nan(), "end was NaN");
82 value.min(self.end)
83 }
84 }
85
86 #[unstable(feature = "clamp_bounds", issue = "147781")]
87 #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
88 const impl ClampBounds<$t> for RangeInclusive<$t> {
89 #[expect(
90 clippy::neg_cmp_op_on_partial_ord,
91 reason = "NaN check is intentionally included in comparison"
92 )]
93 #[inline]
94 fn clamp(self, value: $t) -> $t {
95 let (start, end) = self.into_inner();
96 assert!(start <= end, "start > end, or either was NaN");
97 value.clamp(start, end)
98 }
99 }
100}
101
102impl_for_float!(f16);
104impl_for_float!(f32);
105impl_for_float!(f64);
106impl_for_float!(f128);