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 fn clamp(self, value: $t) -> $t {
70 assert!(!self.start.is_nan(), "start was NaN");
71 value.max(self.start)
72 }
73 }
74
75 #[unstable(feature = "clamp_bounds", issue = "147781")]
76 #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
77 const impl ClampBounds<$t> for RangeToInclusive<$t> {
78 fn clamp(self, value: $t) -> $t {
79 assert!(!self.end.is_nan(), "end was NaN");
80 value.min(self.end)
81 }
82 }
83
84 #[unstable(feature = "clamp_bounds", issue = "147781")]
85 #[rustc_const_unstable(feature = "clamp_bounds", issue = "147781")]
86 const impl ClampBounds<$t> for RangeInclusive<$t> {
87 #[expect(
88 clippy::neg_cmp_op_on_partial_ord,
89 reason = "NaN check is intentionally included in comparison"
90 )]
91 fn clamp(self, value: $t) -> $t {
92 let (start, end) = self.into_inner();
93 assert!(start <= end, "start > end, or either was NaN");
94 value.clamp(start, end)
95 }
96 }
97}
98
99impl_for_float!(f16);
101impl_for_float!(f32);
102impl_for_float!(f64);
103impl_for_float!(f128);