idsp/num.rs
1use dsp_fixedpoint::{Q, Shift};
2use num_traits::{ConstOne, ConstZero, clamp};
3
4/// Constants
5pub trait Clamp: ConstOne + ConstZero + PartialOrd {
6 /// Lowest value
7 ///
8 /// Negative infinity for floating point values.
9 ///
10 /// ```
11 /// # use idsp::Clamp;
12 /// assert_eq!(<i8 as Clamp>::MIN, -128);
13 /// assert_eq!(<f32 as Clamp>::MIN, f32::NEG_INFINITY);
14 /// ```
15 const MIN: Self;
16
17 /// Highest value
18 ///
19 /// Positive infinity for floating point values.
20 ///
21 /// ```
22 /// # use idsp::Clamp;
23 /// assert_eq!(<i8 as Clamp>::MAX, 127);
24 /// ```
25 const MAX: Self;
26
27 /// Clamp
28 fn clamp(self, min: Self, max: Self) -> Self {
29 clamp(self, min, max)
30 }
31}
32
33macro_rules! impl_const_float {
34 ($ty:ident) => {
35 impl Clamp for $ty {
36 const MIN: Self = <$ty>::NEG_INFINITY;
37 const MAX: Self = <$ty>::INFINITY;
38 }
39 };
40}
41impl_const_float!(f32);
42impl_const_float!(f64);
43
44macro_rules! impl_const_int {
45 ($($ty:ident),*) => {$(
46 impl Clamp for $ty {
47 const MIN: Self = <$ty>::MIN;
48 const MAX: Self = <$ty>::MAX;
49 }
50 )*};
51}
52impl_const_int!(
53 i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, isize, usize
54);
55
56impl<T: Clamp + Shift + Copy + PartialOrd, A, const F: i8> Clamp for Q<T, A, F>
57where
58 Self: ConstOne,
59{
60 /// Lowest value
61 ///
62 /// ```
63 /// # use dsp_fixedpoint::Q8;
64 /// # use idsp::Clamp;
65 /// # use num_traits::AsPrimitive;
66 /// assert_eq!(Q8::<4>::MIN, (-16f32).as_());
67 /// ```
68 const MIN: Self = Self::new(T::MIN);
69
70 /// Highest value
71 ///
72 /// ```
73 /// # use dsp_fixedpoint::Q8;
74 /// # use idsp::Clamp;
75 /// # use num_traits::AsPrimitive;
76 /// assert_eq!(Q8::<4>::MAX, (16.0f32 - 1.0 / 16.0).as_());
77 /// ```
78 const MAX: Self = Self::new(T::MAX);
79}