fructose/operators/
trig.rs

1use crate::operators::exp::Exponentiation;
2
3pub trait TrigOps: Exponentiation + Sized {
4    const PI: Self;
5    const TAU: Self;
6    const FRAC_PI_2: Self;
7    const FRAC_PI_3: Self;
8    const FRAC_PI_4: Self;
9    const FRAC_PI_6: Self;
10    const FRAC_PI_8: Self;
11    const FRAC_1_PI: Self;
12    const FRAC_2_PI: Self;
13    const FRAC_2_SQRT_PI: Self;
14
15    fn sin(self) -> Self;
16    fn cos(self) -> Self;
17    fn tan(self) -> Self {
18        self.try_tan().unwrap()
19    }
20    fn sin_cos(self) -> (Self, Self);
21
22    fn try_tan(self) -> Option<Self>;
23
24    fn asin(self) -> Self {
25        self.try_asin().unwrap()
26    }
27    fn acos(self) -> Self {
28        self.try_acos().unwrap()
29    }
30    fn atan(self) -> Self {
31        self.try_atan().unwrap()
32    }
33    fn atan2(self, rhs: Self) -> Self {
34        self.try_atan2(rhs).unwrap()
35    }
36
37    fn try_asin(self) -> Option<Self>;
38    fn try_acos(self) -> Option<Self>;
39    fn try_atan(self) -> Option<Self>;
40    fn try_atan2(self, rhs: Self) -> Option<Self>;
41
42    fn sinh(self) -> Self;
43    fn cosh(self) -> Self;
44    fn tanh(self) -> Self;
45
46    fn coth(self) -> Self {
47        self.try_coth().unwrap()
48    }
49    fn csch(self) -> Self {
50        self.try_csch().unwrap()
51    }
52
53    fn try_coth(self) -> Option<Self>;
54    fn try_csch(self) -> Option<Self>;
55
56    fn asinh(self) -> Self;
57    fn acosh(self) -> Self {
58        self.try_acosh().unwrap()
59    }
60    fn atanh(self) -> Self {
61        self.try_atanh().unwrap()
62    }
63
64    fn try_acosh(self) -> Option<Self>;
65    fn try_atanh(self) -> Option<Self>;
66
67    fn to_degrees(self) -> Self;
68    fn to_radians(self) -> Self;
69}
70
71macro_rules! float_to_option {
72    ($expr:expr) => {{
73        let result = $expr;
74        if result.is_infinite() || result.is_nan() {
75            None
76        } else {
77            Some(result)
78        }
79    }};
80}
81
82macro_rules! impl_trig_float {
83    ($($set:ty => [$($name: ident = $val:expr);* $(;)?]);* $(;)?) => {
84        $(
85                impl TrigOps for $set {
86
87                $(
88                    const $name: $set = $val;
89                )*
90
91                #[inline]
92                fn try_tan(self) -> Option<Self> {
93                    float_to_option!(self.tan())
94                }
95                #[inline]
96                fn try_asin(self) -> Option<Self> {
97                    float_to_option!(self.asin())
98                }
99                #[inline]
100                fn try_acos(self) -> Option<Self> {
101                    float_to_option!(self.acos())
102                }
103                #[inline]
104                fn try_atan(self) -> Option<Self> {
105                    float_to_option!(self.atan())
106                }
107                #[inline]
108                fn try_atan2(self, rhs: Self) -> Option<Self> {
109                    float_to_option!(self.atan2(rhs))
110                }
111                #[inline]
112                fn try_acosh(self) -> Option<Self> {
113                    float_to_option!(self.acosh())
114                }
115                #[inline]
116                fn try_atanh(self) -> Option<Self> {
117                    float_to_option!(self.atanh())
118                }
119                #[inline]
120                fn try_coth(self) -> Option<Self> {
121                    unimplemented!()
122                }
123                #[inline]
124                fn try_csch(self) -> Option<Self> {
125                    unimplemented!()
126                }
127                forward! {
128                    fn sin(self) -> Self;
129                    fn cos(self) -> Self;
130                    fn tan(self) -> Self;
131                    fn sin_cos(self) -> (Self, Self);
132
133                    fn asin(self) -> Self;
134                    fn acos(self) -> Self;
135                    fn atan(self) -> Self;
136                    fn atan2(self, rhs: Self) -> Self;
137
138                    fn sinh(self) -> Self;
139                    fn cosh(self) -> Self;
140                    fn tanh(self) -> Self;
141
142                    fn asinh(self) -> Self;
143                    fn acosh(self) -> Self;
144                    fn atanh(self) -> Self;
145
146                    fn to_degrees(self) -> Self;
147                    fn to_radians(self) -> Self;
148                }
149            }
150        )*
151    }
152}
153
154impl_trig_float! {
155    f32 => [
156        PI              = core::f32::consts::PI;
157        TAU             = core::f32::consts::TAU;
158        FRAC_PI_2       = core::f32::consts::FRAC_PI_2;
159        FRAC_PI_3       = core::f32::consts::FRAC_PI_3;
160        FRAC_PI_4       = core::f32::consts::FRAC_PI_4;
161        FRAC_PI_6       = core::f32::consts::FRAC_PI_6;
162        FRAC_PI_8       = core::f32::consts::FRAC_PI_8;
163        FRAC_1_PI       = core::f32::consts::FRAC_1_PI;
164        FRAC_2_PI       = core::f32::consts::FRAC_2_PI;
165        FRAC_2_SQRT_PI  = core::f32::consts::FRAC_2_SQRT_PI;
166    ];
167    f64 => [
168        PI              = core::f64::consts::PI;
169        TAU             = core::f64::consts::TAU;
170        FRAC_PI_2       = core::f64::consts::FRAC_PI_2;
171        FRAC_PI_3       = core::f64::consts::FRAC_PI_3;
172        FRAC_PI_4       = core::f64::consts::FRAC_PI_4;
173        FRAC_PI_6       = core::f64::consts::FRAC_PI_6;
174        FRAC_PI_8       = core::f64::consts::FRAC_PI_8;
175        FRAC_1_PI       = core::f64::consts::FRAC_1_PI;
176        FRAC_2_PI       = core::f64::consts::FRAC_2_PI;
177        FRAC_2_SQRT_PI  = core::f64::consts::FRAC_2_SQRT_PI;
178    ];
179}