1pub trait RangeOp
13where
14 Self: Sized,
15{
16 type Step;
17
18 fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self;
20
21 fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self;
23}
24
25macro_rules! u_range_op {
26 ($value_ty:ty, $step_ty:ty) => {
27 impl RangeOp for $value_ty {
28 type Step = $step_ty;
29
30 #[inline(always)]
31 fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
32 self.saturating_add(delta).clamp(bounds.0, bounds.1)
33 }
34
35 #[inline(always)]
36 fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
37 self.saturating_sub(delta).clamp(bounds.0, bounds.1)
38 }
39 }
40 };
41}
42
43macro_rules! i_range_op {
44 ($value_ty:ty, $step_ty:ty) => {
45 impl RangeOp for $value_ty {
46 type Step = $step_ty;
47
48 #[inline(always)]
49 fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
50 self.saturating_add_unsigned(delta)
51 .clamp(bounds.0, bounds.1)
52 }
53
54 #[inline(always)]
55 fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
56 self.saturating_sub_unsigned(delta)
57 .clamp(bounds.0, bounds.1)
58 }
59 }
60 };
61}
62
63u_range_op!(u8, u8);
64u_range_op!(u16, u16);
65u_range_op!(u32, u32);
66u_range_op!(u64, u64);
67u_range_op!(u128, u128);
68u_range_op!(usize, usize);
69i_range_op!(i8, u8);
70i_range_op!(i16, u16);
71i_range_op!(i32, u32);
72i_range_op!(i64, u64);
73i_range_op!(i128, u128);
74i_range_op!(isize, usize);
75
76impl RangeOp for f32 {
77 type Step = f32;
78
79 #[inline(always)]
80 fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
81 (self + delta).clamp(bounds.0, bounds.1)
82 }
83
84 #[inline(always)]
85 fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
86 (self - delta).clamp(bounds.0, bounds.1)
87 }
88}
89
90impl RangeOp for f64 {
91 type Step = f64;
92
93 #[inline(always)]
94 fn add_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
95 (self + delta).clamp(bounds.0, bounds.1)
96 }
97
98 #[inline(always)]
99 fn sub_clamp(self, delta: Self::Step, bounds: (Self, Self)) -> Self {
100 (self - delta).clamp(bounds.0, bounds.1)
101 }
102}