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}