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